function preText($s, $prefs) { extract($prefs); callback_event('pretext'); // Set messy variables. $out = makeOut('id', 's', 'c', 'context', 'q', 'm', 'pg', 'p', 'month', 'author'); if (gps('rss')) { $out['feed'] = 'rss'; } if (gps('atom')) { $out['feed'] = 'atom'; } // Some useful vars for taghandlers, plugins. $out['request_uri'] = preg_replace("|^https?://[^/]+|i", "", serverSet('REQUEST_URI')); $out['qs'] = serverSet('QUERY_STRING'); // IIS fix. if (!$out['request_uri'] and serverSet('SCRIPT_NAME')) { $out['request_uri'] = serverSet('SCRIPT_NAME') . (serverSet('QUERY_STRING') ? '?' . serverSet('QUERY_STRING') : ''); } // Another IIS fix. if (!$out['request_uri'] and serverSet('argv')) { $argv = serverSet('argv'); $out['request_uri'] = @substr($argv[0], strpos($argv[0], ';') + 1); } // Define the useable url, minus any subdirectories. // This is pretty ugly, if anyone wants to have a go at it. $out['subpath'] = $subpath = preg_quote(preg_replace("/https?:\\/\\/.*(\\/.*)/Ui", "\$1", hu), "/"); $out['req'] = $req = preg_replace("/^{$subpath}/i", "/", $out['request_uri']); $is_404 = $out['status'] == '404'; // If messy vars exist, bypass URL parsing. if (!$out['id'] && !$out['s'] && !(txpinterface == 'css') && !(txpinterface == 'admin')) { // Return clean URL test results for diagnostics. if (gps('txpcleantest')) { exit(show_clean_test($out)); } extract(chopUrl($req)); // First we sniff out some of the preset URL schemes. if (strlen($u1)) { switch ($u1) { case 'atom': $out['feed'] = 'atom'; break; case 'rss': $out['feed'] = 'rss'; break; // urldecode(strtolower(urlencode())) looks ugly but is the // only way to make it multibyte-safe without breaking // backwards-compatibility. // urldecode(strtolower(urlencode())) looks ugly but is the // only way to make it multibyte-safe without breaking // backwards-compatibility. case urldecode(strtolower(urlencode(gTxt('section')))): $out['s'] = ckEx('section', $u2) ? $u2 : ''; $is_404 = empty($out['s']); break; case urldecode(strtolower(urlencode(gTxt('category')))): if ($u3) { $out['context'] = validContext($u2); $out['c'] = $u3; } else { $out['context'] = 'article'; $out['c'] = $u2; } $out['c'] = ckCat($out['context'], $out['c']) ? $out['c'] : ''; $is_404 = empty($out['c']); break; case urldecode(strtolower(urlencode(gTxt('author')))): if ($u3) { $out['context'] = validContext($u2); $out['author'] = $u3; } else { $out['context'] = 'article'; $out['author'] = $u2; } $out['author'] = !empty($out['author']) ? $out['author'] : ''; break; // AuthorID gets resolved from Name further down. // AuthorID gets resolved from Name further down. case urldecode(strtolower(urlencode(gTxt('file_download')))): $out['s'] = 'file_download'; $out['id'] = !empty($u2) ? $u2 : ''; $out['filename'] = !empty($u3) ? $u3 : ''; break; default: // Then see if the prefs-defined permlink scheme is usable. switch ($permlink_mode) { case 'section_id_title': if (empty($u2)) { $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } else { $rs = lookupByIDSection($u2, $u1); $out['s'] = @$rs['Section']; $out['id'] = @$rs['ID']; $is_404 = (empty($out['s']) or empty($out['id'])); } break; case 'year_month_day_title': if (empty($u2)) { $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } elseif (empty($u4)) { $month = "{$u1}-{$u2}"; if (!empty($u3)) { $month .= "-{$u3}"; } if (preg_match('/\\d+-\\d+(?:-\\d+)?/', $month)) { $out['month'] = $month; $out['s'] = 'default'; } else { $is_404 = 1; } } else { $when = "{$u1}-{$u2}-{$u3}"; $rs = lookupByDateTitle($when, $u4); $out['id'] = !empty($rs['ID']) ? $rs['ID'] : ''; $out['s'] = !empty($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } break; case 'section_title': if (empty($u2)) { $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } else { $rs = lookupByTitleSection($u2, $u1); $out['id'] = isset($rs['ID']) ? $rs['ID'] : ''; $out['s'] = isset($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } break; case 'title_only': $rs = lookupByTitle($u1); $out['id'] = @$rs['ID']; $out['s'] = empty($rs['Section']) ? ckEx('section', $u1) : $rs['Section']; $is_404 = empty($out['s']); break; case 'id_title': if (is_numeric($u1) && ckExID($u1)) { $rs = lookupByID($u1); $out['id'] = !empty($rs['ID']) ? $rs['ID'] : ''; $out['s'] = !empty($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } else { // We don't want to miss the /section/ pages. $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } break; } if (!$is_404) { $out['context'] = validContext($out['context']); } break; // Prefs-defined permlink scheme case. } } else { $out['s'] = 'default'; $out['context'] = validContext($out['context']); } } else { // Messy mode, but prevent to get the id for file_downloads. $out['context'] = validContext($out['context']); if ($out['context'] == 'article' && $out['id'] && $out['s'] != 'file_download') { $rs = lookupByID($out['id']); $out['id'] = !empty($rs['ID']) ? $rs['ID'] : ''; $out['s'] = !empty($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } } // Existing category in messy or clean URL? if (!empty($out['c'])) { if (!ckCat($out['context'], $out['c'])) { $is_404 = true; $out['c'] = ''; } } // Resolve AuthorID from Authorname. if ($out['author']) { $name = urldecode(strtolower(urlencode($out['author']))); $name = safe_field('name', 'txp_users', "RealName LIKE '" . doSlash($out['author']) . "'"); if ($name) { $out['author'] = $name; } else { $out['author'] = ''; $is_404 = true; } } // Allow article preview. if (gps('txpreview')) { doAuth(); if (!has_privs('article.preview')) { txp_status_header('401 Unauthorized'); exit(hed('401 Unauthorized', 1) . graf(gTxt('restricted_area'))); } global $nolog; $nolog = true; $rs = safe_row("ID AS id, Section AS s", 'textpattern', "ID = " . intval(gps('txpreview')) . " LIMIT 1"); if ($rs) { $is_404 = false; $out = array_merge($out, $rs); } } // Stats: found or not. $out['status'] = $is_404 ? '404' : '200'; $out['pg'] = is_numeric($out['pg']) ? intval($out['pg']) : ''; $out['id'] = is_numeric($out['id']) ? intval($out['id']) : ''; if ($out['s'] == 'file_download') { if (is_numeric($out['id'])) { // Undo the double-encoding workaround for .gz files; // @see filedownloadurl(). if (!empty($out['filename'])) { $out['filename'] = preg_replace('/gz&$/i', 'gz', $out['filename']); } $fn = empty($out['filename']) ? '' : " AND filename = '" . doSlash($out['filename']) . "'"; $rs = safe_row('*', 'txp_file', "id = " . intval($out['id']) . " AND status = " . STATUS_LIVE . " AND created <= " . now('created') . $fn); } return !empty($rs) ? array_merge($out, $rs) : array('s' => 'file_download', 'file_error' => 404); } if (!$is_404) { $out['s'] = empty($out['s']) ? 'default' : $out['s']; } $s = $out['s']; $id = $out['id']; // Hackish. global $is_article_list; if (empty($id)) { $is_article_list = true; } // By this point we should know the section, so grab its page and CSS. if (txpinterface != 'css') { $rs = safe_row("page, css", "txp_section", "name = '" . doSlash($s) . "' LIMIT 1"); $out['page'] = isset($rs['page']) ? $rs['page'] : ''; $out['css'] = isset($rs['css']) ? $rs['css'] : ''; } if (is_numeric($id) and !$is_404) { $a = safe_row("*, UNIX_TIMESTAMP(Posted) AS uPosted, UNIX_TIMESTAMP(Expires) AS uExpires, UNIX_TIMESTAMP(LastMod) AS uLastMod", 'textpattern', "ID = " . intval($id) . (gps('txpreview') ? '' : " AND Status IN (" . STATUS_LIVE . "," . STATUS_STICKY . ")")); if ($a) { $out['id_keywords'] = $a['Keywords']; $out['id_author'] = $a['AuthorID']; populateArticleData($a); $uExpires = $a['uExpires']; if ($uExpires and time() > $uExpires and !$publish_expired_articles) { $out['status'] = '410'; } } } // These are deprecated as of Textpattern v1.0 - leaving them here for // plugin compatibility. $out['path_from_root'] = rhu; $out['pfr'] = rhu; $out['path_to_site'] = $path_to_site; $out['permlink_mode'] = $permlink_mode; $out['sitename'] = $sitename; return $out; }
function preText($s, $prefs) { extract($prefs); callback_event('pretext'); // set messy variables $out = makeOut('id', 's', 'c', 'context', 'q', 'm', 'pg', 'p', 'month', 'author'); if (gps('rss')) { include txpath . '/publish/rss.php'; $out['feed'] = 'rss'; } if (gps('atom')) { include txpath . '/publish/atom.php'; $out['feed'] = 'atom'; } // some useful vars for taghandlers, plugins $out['request_uri'] = preg_replace("|^https?://[^/]+|i", "", serverSet('REQUEST_URI')); $out['qs'] = serverSet('QUERY_STRING'); // IIS fix if (!$out['request_uri'] and serverSet('SCRIPT_NAME')) { $out['request_uri'] = serverSet('SCRIPT_NAME') . (serverSet('QUERY_STRING') ? '?' . serverSet('QUERY_STRING') : ''); } // another IIS fix if (!$out['request_uri'] and serverSet('argv')) { $argv = serverSet('argv'); $out['request_uri'] = @substr($argv[0], strpos($argv[0], ';') + 1); } // define the useable url, minus any subdirectories. // this is pretty fugly, if anyone wants to have a go at it - dean $out['subpath'] = $subpath = preg_quote(preg_replace("/https?:\\/\\/.*(\\/.*)/Ui", "\$1", hu), "/"); $out['req'] = $req = preg_replace("/^{$subpath}/i", "/", $out['request_uri']); $is_404 = 0; // if messy vars exist, bypass url parsing if (!$out['id'] && !$out['s'] && !(txpinterface == 'css') && !(txpinterface == 'admin')) { // return clean URL test results for diagnostics if (gps('txpcleantest')) { exit(show_clean_test($out)); } extract(chopUrl($req)); //first we sniff out some of the preset url schemes if (strlen($u1)) { $validTypes = array('article' => gTxt('article_context'), 'image' => gTxt('image_context'), 'file' => gTxt('file_context'), 'link' => gTxt('link_context')); switch ($u1) { case 'atom': include txpath . '/publish/atom.php'; $out['feed'] = 'atom'; break; case 'rss': include txpath . '/publish/rss.php'; $out['feed'] = 'rss'; break; // urldecode(strtolower(urlencode())) looks ugly but is the only way to // make it multibyte-safe without breaking backwards-compatibility // urldecode(strtolower(urlencode())) looks ugly but is the only way to // make it multibyte-safe without breaking backwards-compatibility case urldecode(strtolower(urlencode(gTxt('section')))): $out['s'] = ckEx('section', $u2) ? $u2 : ''; $is_404 = empty($out['s']); break; case urldecode(strtolower(urlencode(gTxt('category')))): if ($u3) { $theType = in_array($u2, $validTypes) ? $u2 : gTxt('article_context'); $theCat = $u3; } else { $theType = gTxt('article_context'); $theCat = $u2; } $typecode = array_search($theType, $validTypes); $out['context'] = $typecode; $out['c'] = ckCat($typecode, $theCat) ? $theCat : ''; $is_404 = empty($out['c']); break; case urldecode(strtolower(urlencode(gTxt('author')))): if ($u3) { $theType = in_array($u2, $validTypes) ? $u2 : gTxt('article_context'); $theAuthor = $u3; } else { $theType = gTxt('article_context'); $theAuthor = $u2; } $typecode = array_search($theType, $validTypes); $out['context'] = $typecode; $out['author'] = !empty($theAuthor) ? $theAuthor : ''; break; // AuthorID gets resolved from Name further down // AuthorID gets resolved from Name further down case urldecode(strtolower(urlencode(gTxt('file_download')))): $out['s'] = 'file_download'; $out['id'] = !empty($u2) ? $u2 : ''; break; default: // then see if the prefs-defined permlink scheme is usable switch ($permlink_mode) { case 'section_id_title': if (empty($u2)) { $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } else { $rs = lookupByIDSection($u2, $u1); $out['s'] = @$rs['Section']; $out['id'] = @$rs['ID']; $is_404 = (empty($out['s']) or empty($out['id'])); } break; case 'year_month_day_title': if (empty($u2)) { $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } elseif (empty($u4)) { $month = "{$u1}-{$u2}"; if (!empty($u3)) { $month .= "-{$u3}"; } if (preg_match('/\\d+-\\d+(?:-\\d+)?/', $month)) { $out['month'] = $month; $out['s'] = 'default'; } else { $is_404 = 1; } } else { $when = "{$u1}-{$u2}-{$u3}"; $rs = lookupByDateTitle($when, $u4); $out['id'] = !empty($rs['ID']) ? $rs['ID'] : ''; $out['s'] = !empty($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } break; case 'section_title': if (empty($u2)) { $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } else { $rs = lookupByTitleSection($u2, $u1); $out['id'] = isset($rs['ID']) ? $rs['ID'] : ''; $out['s'] = isset($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } break; case 'title_only': $rs = lookupByTitle($u1); $out['id'] = @$rs['ID']; $out['s'] = empty($rs['Section']) ? ckEx('section', $u1) : $rs['Section']; $is_404 = empty($out['s']); break; case 'id_title': if (is_numeric($u1) && ckExID($u1)) { $rs = lookupByID($u1); $out['id'] = !empty($rs['ID']) ? $rs['ID'] : ''; $out['s'] = !empty($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } else { # We don't want to miss the /section/ pages $out['s'] = ckEx('section', $u1) ? $u1 : ''; $is_404 = empty($out['s']); } break; } if (!$is_404) { $out['context'] = 'article'; } break; // prefs-defined permlink scheme case } } else { $out['s'] = 'default'; $out['context'] = 'article'; } } else { // Messy mode, but prevent to get the id for file_downloads if ($out['id'] && !$out['s']) { $rs = lookupByID($out['id']); $out['id'] = !empty($rs['ID']) ? $rs['ID'] : ''; $out['s'] = !empty($rs['Section']) ? $rs['Section'] : ''; $is_404 = (empty($out['s']) or empty($out['id'])); } } // Resolve AuthorID from Authorname if ($out['author']) { $name = urldecode(strtolower(urlencode($out['author']))); $name = safe_field('name', 'txp_users', "RealName like '" . doSlash($out['author']) . "'"); if ($name) { $out['author'] = $name; } else { $out['author'] = ''; $is_404 = true; } } // allow article preview if (gps('txpreview') and is_logged_in()) { global $nolog; $nolog = true; $rs = safe_row("ID as id,Section as s", 'textpattern', 'ID = ' . intval(gps('txpreview')) . ' limit 1'); if ($rs and $is_404) { $is_404 = false; $out = array_merge($out, $rs); } } // Stats: found or not $out['status'] = $is_404 ? '404' : '200'; $out['pg'] = is_numeric($out['pg']) ? intval($out['pg']) : ''; $out['id'] = is_numeric($out['id']) ? intval($out['id']) : ''; if ($out['s'] == 'file_download') { // get id of potential filename if (!is_numeric($out['id'])) { $rs = safe_row("*", "txp_file", "filename='" . doSlash($out['id']) . "' and status = 4"); } else { $rs = safe_row("*", "txp_file", 'id=' . intval($out['id']) . ' and status = 4'); } $out = $rs ? array_merge($out, $rs) : array('s' => 'file_download', 'file_error' => 404); return $out; } if (!$is_404) { $out['s'] = empty($out['s']) ? 'default' : $out['s']; } $s = $out['s']; $id = $out['id']; // hackish global $is_article_list; if (empty($id)) { $is_article_list = true; } // by this point we should know the section, so grab its page and css $rs = safe_row("page, css", "txp_section", "name = '" . doSlash($s) . "' limit 1"); $out['page'] = isset($rs['page']) ? $rs['page'] : ''; $out['css'] = isset($rs['css']) ? $rs['css'] : ''; if (is_numeric($id) and !$is_404) { $a = safe_row('*, unix_timestamp(Posted) as uPosted, unix_timestamp(Expires) as uExpires, unix_timestamp(LastMod) as uLastMod', 'textpattern', 'ID=' . intval($id) . (gps('txpreview') ? '' : ' and Status in (4,5)')); if ($a) { $Posted = $a['Posted']; $out['id_keywords'] = $a['Keywords']; $out['id_author'] = $a['AuthorID']; populateArticleData($a); $uExpires = $a['uExpires']; if ($uExpires and time() > $uExpires and !$publish_expired_articles) { $out['status'] = '410'; } if ($np = getNextPrev($id, $Posted, $s)) { $out = array_merge($out, $np); } } } $out['path_from_root'] = rhu; // these are deprecated as of 1.0 $out['pfr'] = rhu; // leaving them here for plugin compat $out['path_to_site'] = $path_to_site; $out['permlink_mode'] = $permlink_mode; $out['sitename'] = $sitename; return $out; }