diff --git a/package.json b/package.json new file mode 100644 index 0000000000..a36c2bf767 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "name": "Textpattern CMS", + "description": "Textpattern is a flexible, elegant and easy-to-use CMS.", + "homepage": "http://textpattern.com", + "textpattern-version": { + "release": "4.6.2", + "prerelease": null + } + } diff --git a/textpattern/checksums.txt b/textpattern/checksums.txt index 8959577cfc..a469e95426 100644 --- a/textpattern/checksums.txt +++ b/textpattern/checksums.txt @@ -51,8 +51,6 @@ /publish/search.php: 3d7e0fcea6f40d31dae8c7fb208e35e6 /publish/taghandlers.php: 5653e0dcd45db67c5607db6d386738fb /textpattern.js: d7654c4b09d4b59f08d72a0701e91771 -/update/_to_1.0.0.php: 038fee881209aae809666177852f0c64 -/update/_to_4.0.2.php: 2fda6b67e48855a503d31b226739c1e8 /update/_to_4.0.3.php: 0ed87e575b17dc7a5c96ae68a3d16397 /update/_to_4.0.4.php: bf3676db9029bcd37c2df43bef3443f0 /update/_to_4.0.5.php: fa4026347c767cfbd6450cd98c9e37f6 diff --git a/textpattern/include/txp_article.php b/textpattern/include/txp_article.php index 24e07333ea..5a9ecea2d6 100644 --- a/textpattern/include/txp_article.php +++ b/textpattern/include/txp_article.php @@ -866,12 +866,7 @@ function article_edit($message = '', $concurrent = false, $refresh_partials = fa $rs['partials_meta'] = &$partials; // Get content for volatile partials. - foreach ($partials as $k => $p) { - if ($p['mode'] == PARTIAL_VOLATILE || $p['mode'] == PARTIAL_VOLATILE_VALUE) { - $cb = $p['cb']; - $partials[$k]['html'] = (is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k)); - } - } + $partials = updatePartials($partials, $rs, array(PARTIAL_VOLATILE, PARTIAL_VOLATILE_VALUE)); if ($refresh_partials) { $response[] = announce($message); @@ -883,40 +878,15 @@ function article_edit($message = '', $concurrent = false, $refresh_partials = fa $response[] = '$("#article_form").addClass("published").removeClass("saved")'; } - // Update the volatile partials. - foreach ($partials as $k => $p) { - // Volatile partials need a target DOM selector. - if (empty($p['selector']) && $p['mode'] != PARTIAL_STATIC) { - trigger_error("Empty selector for partial '$k'", E_USER_ERROR); - } else { - // Build response script. - list($selector, $fragment) = (array)$p['selector'] + array(null, null); - if (!isset($fragment)) { - $fragment = $selector; - } - if ($p['mode'] == PARTIAL_VOLATILE) { - // Volatile partials replace *all* of the existing HTML - // fragment for their selector with the new one. - $response[] = '$("'.$selector.'").replaceWith($("
'.escape_js($p['html']).'
").find("'.$fragment.'"))'; - } elseif ($p['mode'] == PARTIAL_VOLATILE_VALUE) { - // Volatile partial values replace the *value* of elements - // matching their selector. - $response[] = '$("'.$selector.'").val("'.escape_js($p['html']).'")'; - } - } - } + $response = array_merge($response, updateVolatilePartials($partials)); send_script_response(join(";\n", $response)); // Bail out. return; } - foreach ($partials as $k => $p) { - if ($p['mode'] == PARTIAL_STATIC) { - $cb = $p['cb']; - $partials[$k]['html'] = (is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k)); - } - } + // Get content for static partials. + $partials = updatePartials($partials, $rs, PARTIAL_STATIC); $page_title = $ID ? $Title : gTxt('write'); diff --git a/textpattern/include/txp_css.php b/textpattern/include/txp_css.php index e29d65f12a..8eea543516 100644 --- a/textpattern/include/txp_css.php +++ b/textpattern/include/txp_css.php @@ -64,12 +64,11 @@ /** * Renders a list of stylesheets. * - * @param string $current The active stylesheet - * @param string $default Not used + * @param array $current Current record set of the edited sheet * @return string HTML */ -function css_list($current, $default) +function css_list($current) { $out = array(); $protected = safe_column("DISTINCT css", 'txp_section', "1 = 1"); @@ -77,12 +76,12 @@ function css_list($current, $default) $criteria = 1; $criteria .= callback_event('admin_criteria', 'css_list', 0, $criteria); - $rs = safe_rows_start("name", 'txp_css', $criteria); + $rs = safe_rows_start("name", 'txp_css', $criteria . ' ORDER BY name'); if ($rs) { while ($a = nextRow($rs)) { extract($a); - $active = ($current === $name); + $active = ($current['name'] === $name); $edit = eLink('css', '', 'name', $name, $name); @@ -106,16 +105,49 @@ function css_list($current, $default) /** * The main stylesheet editor panel. * - * @param string|array $message The activity message + * @param string|array $message The activity message + * @param bool $refresh_partials Whether to refresh partial contents */ -function css_edit($message = '') +function css_edit($message = '', $refresh_partials = false) { global $event, $step; - pagetop(gTxt('edit_css'), $message); - - $default_name = safe_field("css", 'txp_section', "name = 'default'"); + /* + $partials is an array of: + $key => array ( + 'mode' => {PARTIAL_STATIC | PARTIAL_VOLATILE | PARTIAL_VOLATILE_VALUE}, + 'selector' => $DOM_selector or array($selector, $fragment) of $DOM_selectors, + 'cb' => $callback_function, + 'html' => $return_value_of_callback_function (need not be intialised here) + ) + */ + $partials = array( + // Stylesheet list. + 'list' => array( + 'mode' => PARTIAL_VOLATILE, + 'selector' => '#all_styles', + 'cb' => 'css_list', + ), + // Name field. + 'name' => array( + 'mode' => PARTIAL_VOLATILE, + 'selector' => 'div.name', + 'cb' => 'css_partial_name', + ), + // Name value. + 'name_value' => array( + 'mode' => PARTIAL_VOLATILE_VALUE, + 'selector' => '#new_style,input[name=name]', + 'cb' => 'css_partial_name_value', + ), + // Textarea. + 'css' => array( + 'mode' => PARTIAL_STATIC, + 'selector' => 'div.css', + 'cb' => 'css_partial_css', + ), + ); extract(array_map('assert_string', gpsa(array( 'copy', @@ -123,31 +155,23 @@ function css_edit($message = '') 'savenew', )))); + $default_name = safe_field("css", 'txp_section', "name = 'default'"); + $name = sanitizeForPage(assert_string(gps('name'))); $newname = sanitizeForPage(assert_string(gps('newname'))); + $class = 'async'; if ($step == 'css_delete' || empty($name) && $step != 'pour' && !$savenew) { $name = $default_name; - } elseif (((($copy || $savenew) && $newname) || ($newname && ($newname != $name))) && !$save_error) { + } elseif ((($copy || $savenew) && $newname) && !$save_error) { $name = $newname; + } elseif ((($newname && ($newname != $name)) || $step === 'pour') && !$save_error) { + $name = $newname; + $class = ''; + } elseif ($savenew && $save_error) { + $class = ''; } - $titleblock = inputLabel( - 'new_style', - fInput('text', 'newname', $name, 'input-medium', '', '', INPUT_MEDIUM, '', 'new_style', false, true), - 'css_name', - array('', 'instructions_style_name'), - array('class' => 'txp-form-field name') - ); - - if ($name === '') { - $titleblock .= hInput('savenew', 'savenew'); - } else { - $titleblock .= hInput('name', $name); - } - - $titleblock .= eInput('css').sInput('css_save'); - $thecss = gps('css'); if (!$save_error) { @@ -178,6 +202,30 @@ function css_edit($message = '') )), ' class="txp-save"' ); + $rs = array( + 'name' => $name, + 'newname' => $newname, + 'default' => $default_name, + 'css' => $thecss, + ); + + // Get content for volatile partials. + $partials = updatePartials($partials, $rs, array(PARTIAL_VOLATILE, PARTIAL_VOLATILE_VALUE)); + + if ($refresh_partials) { + $response[] = announce($message); + $response = array_merge($response, updateVolatilePartials($partials)); + send_script_response(join(";\n", $response)); + + // Bail out. + return; + } + + // Get content for static partials. + $partials = updatePartials($partials, $rs, PARTIAL_STATIC); + + pagetop(gTxt('edit_css'), $message); + echo n.'
'. n.tag( hed(gTxt('tab_style'), 1, array('class' => 'txp-heading')), @@ -185,9 +233,8 @@ function css_edit($message = '') ); // Styles create/switcher column. - echo n.tag( - css_list($name, $default_name).n, + $partials['list']['html'].n, 'div', array( 'class' => 'txp-layout-4col-alt', 'id' => 'content_switcher', @@ -196,19 +243,12 @@ function css_edit($message = '') ); // Styles code columm. - echo n.tag( form( $actions. - $titleblock. - inputLabel( - 'css', - '', - 'css_code', - array('', 'instructions_style_code'), - array('class' => 'txp-form-field') - ). - $buttons, '', '', 'post', '', '', 'style_form'), + $partials['name']['html']. + $partials['css']['html']. + $buttons, '', '', 'post', $class, '', 'style_form'), 'div', array( 'class' => 'txp-layout-4col-3span', 'id' => 'main_content', @@ -225,6 +265,8 @@ function css_edit($message = '') function css_save() { + global $app_mode; + extract(doSlash(array_map('assert_string', psa(array( 'savenew', 'copy', @@ -250,6 +292,7 @@ function css_save() if (($newname !== $name) && $exists) { $message = array(gTxt('css_already_exists', array('{name}' => $newname)), E_ERROR); + if ($savenew) { $_POST['newname'] = ''; } @@ -273,7 +316,7 @@ function css_save() if (safe_update('txp_css', "css = '$css', name = '".doSlash($newname)."'", "name = '".doSlash($name)."'")) { safe_update('txp_section', "css = '".doSlash($newname)."'", "css='".doSlash($name)."'"); update_lastmod('css_saved', compact('newname', 'name', 'css')); - $message = gTxt('css_updated', array('{name}' => $name)); + $message = gTxt('css_updated', array('{name}' => $newname)); } else { $message = array(gTxt('css_save_failed'), E_ERROR); $save_error = true; @@ -288,7 +331,7 @@ function css_save() callback_event('css_saved', '', 0, $name, $newname); } - css_edit($message); + css_edit($message, ($app_mode === 'async') ? true : false); } /** @@ -311,3 +354,66 @@ function css_delete() } css_edit($message); } + +/** + * Renders css name field. + * + * @param array $rs Record set + * @return string HTML + */ + +function css_partial_name($rs) +{ + $name = $rs['name']; + $newname = $rs['newname']; + + $titleblock = inputLabel( + 'new_style', + fInput('text', 'newname', $name, 'input-medium', '', '', INPUT_MEDIUM, '', 'new_style', false, true), + 'css_name', + array('', 'instructions_style_name'), + array('class' => 'txp-form-field name') + ); + + if ($name === '') { + $titleblock .= hInput('savenew', 'savenew'); + } else { + $titleblock .= hInput('name', $name); + } + + $titleblock .= eInput('css').sInput('css_save'); + + return $titleblock; +} + +/** + * Renders css name field. + * + * @param array $rs Record set + * @return string HTML + */ + +function css_partial_name_value($rs) +{ + return $rs['name']; +} + +/** + * Renders css textarea field. + * + * @param array $rs Record set + * @return string HTML + */ + +function css_partial_css($rs) +{ + $out = inputLabel( + 'css', + '', + 'css_code', + array('', 'instructions_style_code'), + array('class' => 'txp-form-field css') + ); + + return $out; +} diff --git a/textpattern/lib/txplib_db.php b/textpattern/lib/txplib_db.php index 9c4c4017e3..f5221e0572 100644 --- a/textpattern/lib/txplib_db.php +++ b/textpattern/lib/txplib_db.php @@ -1454,6 +1454,7 @@ function db_down() + Database unavailable diff --git a/textpattern/lib/txplib_html.php b/textpattern/lib/txplib_html.php index 3df7abd765..c2f229bdc0 100644 --- a/textpattern/lib/txplib_html.php +++ b/textpattern/lib/txplib_html.php @@ -1255,7 +1255,7 @@ function fieldHelp($help_var) $ui = n.tag($help_text, 'div', array('class' => 'txp-form-field-instructions')); - return pluggable_ui('admin_help_field', $help_var, $ui, compact('help_var', 'textile')); + return pluggable_ui('admin_help_field', $help_var, $ui, compact('help_var')); } /** diff --git a/textpattern/lib/txplib_misc.php b/textpattern/lib/txplib_misc.php index 484de35201..11e40dfb19 100644 --- a/textpattern/lib/txplib_misc.php +++ b/textpattern/lib/txplib_misc.php @@ -371,6 +371,68 @@ function gTxtScript($var, $atts = array(), $route = array()) } } +/** + * Handle refreshing the passed AJAX content to the UI. + * + * @param array $partials Partials array + * @param array $rs Record set of the edited content + */ + +function updatePartials($partials, $rs, $types) +{ + if (!is_array($types)) { + $types = array($types); + } + + foreach ($partials as $k => $p) { + if (in_array($p['mode'], $types)) { + $cb = $p['cb']; + $partials[$k]['html'] = (is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k)); + } + } + + return $partials; +} + +/** + * Handle refreshing the passed AJAX content to the UI. + * + * @param array $partials Partials array + * @return array Response to send back to the browser + */ + +function updateVolatilePartials($partials) +{ + $response = array(); + + // Update the volatile partials. + foreach ($partials as $k => $p) { + // Volatile partials need a target DOM selector. + if (empty($p['selector']) && $p['mode'] != PARTIAL_STATIC) { + trigger_error("Empty selector for partial '$k'", E_USER_ERROR); + } else { + // Build response script. + list($selector, $fragment) = (array)$p['selector'] + array(null, null); + + if (!isset($fragment)) { + $fragment = $selector; + } + + if ($p['mode'] == PARTIAL_VOLATILE) { + // Volatile partials replace *all* of the existing HTML + // fragment for their selector with the new one. + $response[] = '$("'.$selector.'").replaceWith($("
'.escape_js($p['html']).'
").find("'.$fragment.'"))'; + } elseif ($p['mode'] == PARTIAL_VOLATILE_VALUE) { + // Volatile partial values replace the *value* of elements + // matching their selector. + $response[] = '$("'.$selector.'").val("'.escape_js($p['html']).'")'; + } + } + } + + return $response; +} + /** * Returns given timestamp in a format of 01 Jan 2001 15:19:16. * @@ -4486,40 +4548,51 @@ function get_lastmod($unix_ts = null) function handle_lastmod($unix_ts = null, $exit = true) { - if (get_pref('send_lastmod') && get_pref('production_status') == 'live') { + // Disable caching when not in production + if (get_pref('production_status') != 'live') { + header('Cache-Control: no-cache, no-store, max-age=0'); + } + + elseif (get_pref('send_lastmod') && get_pref('production_status') == 'live') { $unix_ts = get_lastmod($unix_ts); // Make sure lastmod isn't in the future. $unix_ts = min($unix_ts, time()); - // Or too far in the past (7 days). - $unix_ts = max($unix_ts, time() - 3600 * 24 * 7); - $last = safe_strftime('rfc822', $unix_ts, 1); header("Last-Modified: $last"); - header('Cache-Control: no-cache'); - $hims = serverSet('HTTP_IF_MODIFIED_SINCE'); + $etag = base_convert($unix_ts, 10, 32); + header('ETag: "' . $etag . '"'); + + // Get timestamp from request caching headers + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + $hims = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $imsd = ($hims) ? strtotime($hims) : 0; + } elseif (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { + $hinm = trim(trim($_SERVER['HTTP_IF_NONE_MATCH']), '"'); + $hinm_apache_gzip_workaround = explode('-gzip', $hinm); + $hinm_apache_gzip_workaround = $hinm_apache_gzip_workaround[0]; + $inmd = ($hinm) ? base_convert($hinm_apache_gzip_workaround, 32, 10) : 0; + } - if ($hims and @strtotime($hims) >= $unix_ts) { + // Check request timestamps against the current timestamp + if ((isset($imsd) && $imsd >= $unix_ts) || + (isset($inmd) && $inmd >= $unix_ts)) { log_hit('304'); - if (!$exit) { - return array('304', $last); - } + header('Content-Length: 0'); txp_status_header('304 Not Modified'); - header('Content-Length: 0'); + if ($exit) { + exit(); + } - // Discard all output. - while (@ob_end_clean()); - exit; + return array('304', $last); } - if (!$exit) { - return array('200', $last); - } + return array('200', $last); } } @@ -5041,6 +5114,7 @@ function txp_die($msg, $status = '503', $url = '') + Textpattern Error: <txp:error_status /> diff --git a/textpattern/lib/txplib_publish.php b/textpattern/lib/txplib_publish.php index eb5187e43d..bf3c931bed 100644 --- a/textpattern/lib/txplib_publish.php +++ b/textpattern/lib/txplib_publish.php @@ -365,7 +365,7 @@ function lastMod() function parse($thing, $condition = null) { - global $production_status, $trace, $txp_parsed, $txp_else, $txp_current_tag; + global $production_status, $trace, $txp_parsed, $txp_else; if (isset($condition)) { if ($production_status === 'debug') { @@ -488,10 +488,7 @@ function parse($thing, $condition = null) for ($out = $tag[$first - 1]; $first <= $last; $first++) { $t = $tag[$first]; - $old_tag = $txp_current_tag; - $txp_current_tag = $t[0].$t[3].$t[4]; $out .= processTags($t[1], $t[2], $t[3]).$tag[++$first]; - $txp_current_tag = $old_tag; } return $out; @@ -537,19 +534,22 @@ function processTags($tag, $atts, $thing = null) } if ($production_status !== 'live') { - $trace->start('' : '/>')); + $old_tag = $txp_current_tag; + $txp_current_tag = '' : '/>'); + $trace->start($txp_current_tag); } if ($registry === null) { $registry = Txp::get('\Textpattern\Tag\Registry'); } - $out = $registry->process($tag, splat($atts), $thing); + $split = splat($atts); + $out = $registry->process($tag, $split, $thing); if ($out === false) { if (maybe_tag($tag)) { // Deprecated in 4.6.0. trigger_error(gTxt('unregistered_tag'), E_USER_NOTICE); - $out = $registry->register($tag)->process($tag, splat($atts), $thing); + $out = $registry->register($tag)->process($tag, $split, $thing); } else { trigger_error(gTxt('unknown_tag'), E_USER_WARNING); $out = ''; @@ -558,6 +558,7 @@ function processTags($tag, $atts, $thing = null) if ($production_status !== 'live') { $trace->stop(isset($thing) ? "" : null); + $txp_current_tag = $old_tag; } return $out; diff --git a/textpattern/lib/txplib_wrapper.php b/textpattern/lib/txplib_wrapper.php index 0c4e334205..13d285d7bc 100644 --- a/textpattern/lib/txplib_wrapper.php +++ b/textpattern/lib/txplib_wrapper.php @@ -387,7 +387,7 @@ public function newArticle($params) * $wrapper = new TXP_wrapper('username', 'password'); * if ($sections = $wrapper->getSectionsList()) * { - * foreach($sections as $section) + * foreach ($sections as $section) * { * echo $section['title']; * } @@ -439,7 +439,7 @@ public function getSection($name) * $wrapper = new TXP_wrapper('username', 'password'); * if ($categories = $wrapper->getCategoryList()) * { - * foreach($categories as $category) + * foreach ($categories as $category) * { * echo $category['title']; * } diff --git a/textpattern/publish/atom.php b/textpattern/publish/atom.php index 93de1f78e4..bcb718b024 100644 --- a/textpattern/publish/atom.php +++ b/textpattern/publish/atom.php @@ -226,6 +226,7 @@ function atom() if (!trim($summary)) { $summary = $content; } + $content = ''; } @@ -239,7 +240,6 @@ function atom() $articles[$ID] = tag(n.t.t.join(n.t.t, $e).n.$cb, 'entry'); - $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); $dates[$ID] = $uLastMod; } } @@ -267,7 +267,6 @@ function atom() $articles[$id] = tag(n.t.t.join(n.t.t, $e).n, 'entry'); - $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); $dates[$id] = $date; } } @@ -284,75 +283,57 @@ function atom() if (safe_field("id", 'txp_category', "name = '$category' AND type = 'link'") == false) { txp_die(gTxt('404_not_found'), '404'); } + break; case 'article': default: if (safe_field("id", 'txp_category', "name IN ('".join("','", $category)."') AND type = 'article'") == false) { txp_die(gTxt('404_not_found'), '404'); } + break; } } } else { - handle_lastmod(); - $hims = serverset('HTTP_IF_MODIFIED_SINCE'); - $imsd = ($hims) ? strtotime($hims) : 0; - - if (is_callable('apache_request_headers')) { - $headers = apache_request_headers(); - - if (isset($headers["A-IM"])) { - $canaim = strpos($headers["A-IM"], "feed"); - } else { - $canaim = false; - } - } else { - $canaim = false; + header('Vary: A-IM, If-None-Match, If-Modified-Since'); + + handle_lastmod(max($dates)); + + // Get timestamp from request caching headers + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + $hims = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $imsd = ($hims) ? strtotime($hims) : 0; + } elseif (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { + $hinm = trim(trim($_SERVER['HTTP_IF_NONE_MATCH']), '"'); + $hinm_apache_gzip_workaround = explode('-gzip', $hinm); + $hinm_apache_gzip_workaround = $hinm_apache_gzip_workaround[0]; + $inmd = ($hinm) ? base_convert($hinm_apache_gzip_workaround, 32, 10) : 0; } - $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); + if (isset($imsd) || isset($inmd)) { + $clfd = max(intval($imsd), intval($inmd)); + } $cutarticles = false; - if ($canaim !== false) { - foreach ($articles as $id => $thing) { - if (strpos($hinm, $etags[$id])) { - unset($articles[$id]); - $cutarticles = true; - $cut_etag = true; - } + if (isset($_SERVER["HTTP_A_IM"]) && + strpos($_SERVER["HTTP_A_IM"], "feed") && + isset($clfd) && $clfd > 0) { - if ($dates[$id] < $imsd) { + // Remove articles with timestamps older than the request timestamp + foreach ($articles as $id => $entry) { + if ($dates[$id] <= $clfd) { unset($articles[$id]); $cutarticles = true; - $cut_time = true; } } } - if (isset($cut_etag) && isset($cut_time)) { - header("Vary: If-None-Match, If-Modified-Since"); - } elseif (isset($cut_etag)) { - header("Vary: If-None-Match"); - } elseif (isset($cut_time)) { - header("Vary: If-Modified-Since"); - } - - $etag = @join("-", $etags); - - if (strstr($hinm, $etag)) { - txp_status_header('304 Not Modified'); - exit(0); - } - - if ($etag) { - header('ETag: "'.$etag.'"'); - } - + // Indicate that instance manipulation was applied if ($cutarticles) { header("HTTP/1.1 226 IM Used"); - header("Cache-Control: no-store, im"); - header("IM: feed"); + header("Cache-Control: IM", false); + header("IM: feed", false); } } @@ -360,6 +341,9 @@ function atom() header('Content-Type: application/atom+xml; charset=utf-8'); - return chr(60).'?xml version="1.0" encoding="UTF-8"?'.chr(62).n. - ''.join(n, $out).''; + return + ''.n. + ''.n. + join(n, $out).n. + ''; } diff --git a/textpattern/publish/rss.php b/textpattern/publish/rss.php index 3ab26fe7c9..53a395d626 100644 --- a/textpattern/publish/rss.php +++ b/textpattern/publish/rss.php @@ -171,8 +171,7 @@ function rss() $articles[$ID] = tag($item, 'item'); - $etags[$ID] = strtoupper(dechex(crc32($articles[$ID]))); - $dates[$ID] = $uPosted; + $dates[$ID] = $uLastMod; } } } elseif ($area == 'link') { @@ -192,8 +191,7 @@ function rss() tag(safe_strftime('rfc822', $uDate), 'pubDate'); $articles[$id] = tag($item, 'item'); - $etags[$id] = strtoupper(dechex(crc32($articles[$id]))); - $dates[$id] = $date; + $dates[$id] = $uLastMod; } } } @@ -209,71 +207,57 @@ function rss() if (safe_field("id", 'txp_category', "name = '$category' AND type = 'link'") == false) { txp_die(gTxt('404_not_found'), '404'); } + break; case 'article': default: if (safe_field("id", 'txp_category', "name IN ('".join("','", $category)."') AND type = 'article'") == false) { txp_die(gTxt('404_not_found'), '404'); } + break; } } } else { - handle_lastmod(); - $hims = serverset('HTTP_IF_MODIFIED_SINCE'); - $imsd = ($hims) ? strtotime($hims) : 0; - - if (is_callable('apache_request_headers')) { - $headers = apache_request_headers(); - - if (isset($headers["A-IM"])) { - $canaim = strpos($headers["A-IM"], "feed"); - } else { - $canaim = false; - } - } else { - $canaim = false; + header('Vary: A-IM, If-None-Match, If-Modified-Since'); + + handle_lastmod(max($dates)); + + // Get timestamp from request caching headers + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + $hims = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $imsd = ($hims) ? strtotime($hims) : 0; + } elseif (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { + $hinm = trim(trim($_SERVER['HTTP_IF_NONE_MATCH']), '"'); + $hinm_apache_gzip_workaround = explode('-gzip', $hinm); + $hinm_apache_gzip_workaround = $hinm_apache_gzip_workaround[0]; + $inmd = ($hinm) ? base_convert($hinm_apache_gzip_workaround, 32, 10) : 0; } - $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH')); + if (isset($imsd) || isset($inmd)) { + $clfd = max(intval($imsd), intval($inmd)); + } $cutarticles = false; - if ($canaim !== false) { - foreach ($articles as $id => $thing) { - if (strpos($hinm, $etags[$id]) !== false) { - unset($articles[$id]); - $cutarticles = true; - $cut_etag = true; - } + if (isset($_SERVER["HTTP_A_IM"]) && + strpos($_SERVER["HTTP_A_IM"], "feed") && + isset($clfd) && $clfd > 0) { - if ($dates[$id] < $imsd) { + // Remove articles with timestamps older than the request timestamp + foreach ($articles as $id => $entry) { + if ($dates[$id] <= $clfd) { unset($articles[$id]); $cutarticles = true; - $cut_time = true; } } } - if (isset($cut_etag) && isset($cut_time)) { - header("Vary: If-None-Match, If-Modified-Since"); - } elseif (isset($cut_etag)) { - header("Vary: If-None-Match"); - } elseif (isset($cut_time)) { - header("Vary: If-Modified-Since"); - } - - $etag = @join("-", $etags); - - if (strstr($hinm, $etag)) { - txp_status_header('304 Not Modified'); - exit(0); - } - + // Indicate that instance manipulation was applied if ($cutarticles) { header("HTTP/1.1 226 IM Used"); - header("Cache-Control: no-store, im"); - header("IM: feed"); + header("Cache-Control: IM", false); + header("IM: feed", false); } } @@ -281,10 +265,6 @@ function rss() header("Content-Type: application/rss+xml; charset=utf-8"); - if (isset($etag)) { - header('ETag: "'.$etag.'"'); - } - return ''.n. ''.n. diff --git a/textpattern/publish/taghandlers.php b/textpattern/publish/taghandlers.php index 7d4c560959..f82d630b09 100644 --- a/textpattern/publish/taghandlers.php +++ b/textpattern/publish/taghandlers.php @@ -522,15 +522,18 @@ function feed_link($atts, $thing = null) $title = txpspecialchars($title); - if ($format == 'link') { - $type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml'; + $type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml'; + if ($format == 'link') { return ''; } $txt = ($thing === null ? $label : parse($thing)); - $out = href($txt, $url, ' title="'.$title.'"'); + $out = href($txt, $url, array( + 'type' => $type, + 'title' => $title, + )); return ($wraptag) ? doTag($out, $wraptag, $class) : $out; } @@ -563,13 +566,16 @@ function link_feed_link($atts) $title = txpspecialchars($title); - if ($format == 'link') { - $type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml'; + $type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml'; + if ($format == 'link') { return ''; } - $out = href($label, $url, ' title="'.$title.'"'); + $out = href($label, $url, array( + 'type' => $type, + 'title' => $title, + )); return ($wraptag) ? doTag($out, $wraptag, $class) : $out; } @@ -1733,10 +1739,10 @@ function link_to_home($atts, $thing = null) function newer($atts, $thing = null) { - global $thispage, $pretext, $m, $txp_current_tag; + global $thispage, $pretext, $m; if (empty($thispage)) { - return empty($pretext['secondpass']) ? $txp_current_tag : ''; + return ''; } extract(lAtts(array( @@ -1791,10 +1797,10 @@ function newer($atts, $thing = null) function older($atts, $thing = null) { - global $thispage, $pretext, $m, $txp_current_tag; + global $thispage, $pretext, $m; if (empty($thispage)) { - return empty($pretext['secondpass']) ? $txp_current_tag : ''; + return ''; } extract(lAtts(array( @@ -3274,10 +3280,10 @@ function search_result_date($atts) function search_result_count($atts) { - global $pretext, $thispage, $txp_current_tag; + global $thispage; if (empty($thispage)) { - return empty($pretext['secondpass']) ? $txp_current_tag : ''; + return ''; } $t = @$thispage['grand_total']; @@ -3894,7 +3900,8 @@ function if_description($atts, $thing = null) 'type' => null, ), $atts)); - $x = !empty(getMetaDescription($type)); + $content = getMetaDescription($type); + $x = !empty($content); return isset($thing) ? parse($thing, $x) : $x;; } @@ -4063,16 +4070,12 @@ function if_search($atts, $thing = null) function if_search_results($atts, $thing = null) { - global $thispage, $pretext, $txp_current_tag; + global $pretext, $thispage; - if (empty($pretext['q'])) { + if (empty($pretext['q']) || empty($thispage)) { return ''; } - if (empty($thispage)) { - return empty($pretext['secondpass']) ? $txp_current_tag : ''; - } - extract(lAtts(array( 'min' => 1, 'max' => 0, @@ -4138,11 +4141,11 @@ function if_article_category($atts, $thing = null) } if ($name) { - $x = !empty(array_intersect(do_list($name), $cats)); - } else { - $x = !empty($cats); + $cats = array_intersect(do_list($name), $cats); } + $x = !empty($cats); + return isset($thing) ? parse($thing, $x) : $x; } @@ -4929,9 +4932,57 @@ function file_download_description($atts) // ------------------------------------------------------------- -function hide() +function hide($atts, $thing=null) { - return ''; + global $txp_parsed, $txp_else; + + if (empty($atts)) { + return ''; + } + + extract(lAtts(array( + 'test' => false, + 'insert' => false, + 'ignore' => false + ), $atts)); + + $test = $test === true || empty($test) || is_numeric($test) ? array() : do_list_unique($test); + $insert = $insert ? do_list_unique($insert) : array(); + $ignore = $ignore ? do_list_unique($ignore) : array(); + + $hash = sha1($thing); + $tag = $txp_parsed[$hash]; + + if (empty($tag)) { + return $thing; + } + + $nr = $txp_else[$hash][0] - 2; + $out = array($tag[0]); + + for ($isempty = true, $tags = array(), $n = 1; $n <= $nr; $n++) { + $t = $tag[$n]; + + if (in_array($t[1], $insert)) { + $out[] = $t; + $tags[] = $n; + } else { + $nextag = processTags($t[1], $t[2], $t[3]); + $out[] = $nextag; + $isempty &= trim($nextag) === '' || ($test ? !in_array($t[1], $test) : in_array($t[1], $ignore)); + } + + $out[] = $tag[++$n]; + } + + if (!$isempty) { + foreach ($tags as $n) { + $t = $out[$n]; + $out[$n] = processTags($t[1], $t[2], $t[3]); + } + } + + return $isempty ? parse($thing, false) : implode('', $out); } // ------------------------------------------------------------- diff --git a/textpattern/setup/forms/article.search_results.txp b/textpattern/setup/forms/article.search_results.txp index f54feeef37..e9a868adf6 100644 --- a/textpattern/setup/forms/article.search_results.txp +++ b/textpattern/setup/forms/article.search_results.txp @@ -64,27 +64,21 @@ - + + +

+ + + - - - -

- - - - - - - - - -

- + + + +

+
diff --git a/textpattern/setup/pages/archive.txp b/textpattern/setup/pages/archive.txp index 3a13589786..eda3af6c35 100644 --- a/textpattern/setup/pages/archive.txp +++ b/textpattern/setup/pages/archive.txp @@ -22,7 +22,7 @@ - + @@ -85,59 +85,43 @@ - - - - - - - + +

- - + - + - - + - +

-
+ - - - - - - - + +

- - + - + - - + - +

-
+ @@ -178,7 +162,7 @@

- ">Textpattern CMS + ">Textpattern CMS

diff --git a/textpattern/setup/pages/default.txp b/textpattern/setup/pages/default.txp index 82ba319cec..61d92a70f4 100644 --- a/textpattern/setup/pages/default.txp +++ b/textpattern/setup/pages/default.txp @@ -144,30 +144,22 @@ - - - - - - - + +

- - + - + - - + - +

-
+ @@ -208,7 +200,7 @@

- ">Textpattern CMS + ">Textpattern CMS

diff --git a/textpattern/setup/pages/error_default.txp b/textpattern/setup/pages/error_default.txp index 6d9de29514..96d5544edc 100644 --- a/textpattern/setup/pages/error_default.txp +++ b/textpattern/setup/pages/error_default.txp @@ -102,7 +102,7 @@

- ">Textpattern CMS + ">Textpattern CMS

diff --git a/textpattern/textpattern.js b/textpattern/textpattern.js index 1517e2d646..6f74a08bf0 100644 --- a/textpattern/textpattern.js +++ b/textpattern/textpattern.js @@ -1862,8 +1862,9 @@ textpattern.Route.add('css, page, form', function () e.preventDefault(); var target = $(this).data('form'); if (target) { - $('#'+target).append(''); - $('.txp-save input').click(); + var $target = $('#'+target); + $target.append(''); + $target.off('submit.txpAsyncForm').trigger('submit'); } }); }); diff --git a/textpattern/update/_to_1.0.0.php b/textpattern/update/_to_1.0.0.php deleted file mode 100644 index d5d5573cdc..0000000000 --- a/textpattern/update/_to_1.0.0.php +++ /dev/null @@ -1,708 +0,0 @@ -. - */ - -if (!defined('TXP_UPDATE')) { - exit("Nothing here. You can't access this file directly."); -} - -safe_delete('txp_category', "name = ''"); -safe_delete('txp_category', "name = ' '"); - -$txpcat = getThings("DESCRIBE `".PFX."txp_category`"); - -if (!in_array('id', $txpcat)) { - safe_alter('txp_category', "ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST"); -} - -if (!in_array('parent', $txpcat)) { - safe_alter('txp_category', "ADD parent VARCHAR(64) NOT NULL DEFAULT ''"); -} - -if (!in_array('lft', $txpcat)) { - safe_alter('txp_category', "ADD lft INT NOT NULL DEFAULT '0'"); -} - -if (!in_array('rgt', $txpcat)) { - safe_alter('txp_category', "ADD rgt INT NOT NULL DEFAULT '0'"); -} - -if (in_array('level', $txpcat)) { - safe_alter('txp_category', "DROP level"); -} - -$txp = getThings("DESCRIBE `".PFX."textpattern`"); - -if (!in_array('Keywords', $txp)) { - safe_alter('textpattern', "ADD Keywords VARCHAR(255) NOT NULL"); -} - -if (in_array('Listing1', $txp) && !in_array('textile_body', $txp)) { - safe_alter('textpattern', "CHANGE Listing1 textile_body INT DEFAULT '1' NOT NULL"); -} - -if (in_array('Listing2', $txp) && !in_array('textile_excerpt', $txp)) { - safe_alter('textpattern', "CHANGE Listing2 textile_excerpt INT DEFAULT '1' NOT NULL"); -} - -if (!in_array('url_title', $txp)) { - safe_alter('textpattern', "ADD url_title VARCHAR(255) NOT NULL"); -} - -if (!in_array('Excerpt', $txp)) { - safe_alter('textpattern', "ADD Excerpt MEDIUMTEXT NOT NULL AFTER Body_html"); -} - -// Excerpt_html added in 1.0. -if (!in_array('Excerpt_html', $txp)) { - safe_alter('textpattern', "ADD Excerpt_html MEDIUMTEXT NOT NULL AFTER Excerpt "); -} - -// Comments count cache field. -if (!in_array('comments_count', $txp)) { - safe_alter('textpattern', "ADD comments_count INT NOT NULL AFTER AnnotateInvite "); -} - -// Custom fields added for g1.19. -if (!in_array('custom_1', $txp)) { - safe_alter('textpattern', "ADD custom_1 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_2', $txp)) { - safe_alter('textpattern', "ADD custom_2 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_3', $txp)) { - safe_alter('textpattern', "ADD custom_3 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_4', $txp)) { - safe_alter('textpattern', "ADD custom_4 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_5', $txp)) { - safe_alter('textpattern', "ADD custom_5 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_6', $txp)) { - safe_alter('textpattern', "ADD custom_6 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_7', $txp)) { - safe_alter('textpattern', "ADD custom_7 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_8', $txp)) { - safe_alter('textpattern', "ADD custom_8 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_9', $txp)) { - safe_alter('textpattern', "ADD custom_9 VARCHAR(255) NOT NULL"); -} - -if (!in_array('custom_10', $txp)) { - safe_alter('textpattern', "ADD custom_10 VARCHAR(255) NOT NULL"); -} - -$txpsect = getThings("DESCRIBE `".PFX."txp_section`"); - -if (!in_array('searchable', $txpsect)) { - safe_alter('txp_section', "ADD searchable INT NOT NULL DEFAULT 1"); -} - -$txpuser = getThings("DESCRIBE `".PFX."txp_users`"); - -if (!in_array('nonce', $txpuser)) { - safe_alter('txp_users', "ADD nonce VARCHAR(64) NOT NULL"); -}; - -// 1.0rc: checking nonce in txp_users table. -$txpusers = safe_rows_start("name, nonce", 'txp_users', "1 = 1"); - -if ($txpusers) { - while ($a = nextRow($txpusers)) { - extract($a); - if (!$nonce) { - $nonce = md5(uniqid(rand(), true)); - safe_update('txp_users', "nonce = '$nonce'", "name = '".doSlash($name)."'"); - } - } -} - -// 1.0rc: expanding password field in txp_users. -safe_alter('txp_users', "MODIFY pass VARCHAR(128) NOT NULL"); - -safe_alter('textpattern', "MODIFY Body MEDIUMTEXT NOT NULL"); -safe_alter('textpattern', "MODIFY Body_html MEDIUMTEXT NOT NULL"); -safe_alter('textpattern', "MODIFY Excerpt TEXT NOT NULL"); - -$popcom = fetch("*", 'txp_form', 'name', "popup_comments"); - -if (!$popcom) { - $popform = << - - - - -<txp:page_title /> - - -
- - - -
- - -eod; - $popform = addslashes($popform); - safe_insert('txp_form', "name = 'popup_comments', type = 'comment', Form = '$popform'"); -} - -safe_update('txp_category', "lft = 0, rgt = 0", "name != 'root'"); - -safe_delete('txp_category', "name = 'root'"); - -safe_update('txp_category', "parent = 'root'", "parent = ''"); - -safe_insert('txp_category', "name = 'root', parent = '', type = 'article', lft = 1, rgt = 0"); -rebuild_tree('root', 1, 'article'); - -safe_insert('txp_category', "name = 'root', parent = '', type = 'link', lft = 1, rgt = 0"); -rebuild_tree('root', 1, 'link'); - -safe_insert('txp_category', "name = 'root', parent = '', type = 'image', lft = 1, rgt = 0"); -rebuild_tree('root', 1, 'image'); - -if (safe_field("val", 'txp_prefs', "name = 'article_list_pageby'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'article_list_pageby', val = 25"); -} - -if (safe_field("val", 'txp_prefs', "name = 'link_list_pageby'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'link_list_pageby', val = 25"); -} - -if (safe_field("val", 'txp_prefs', "name = 'image_list_pageby'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'image_list_pageby', val = 25"); -} - -if (safe_field("val", 'txp_prefs', "name = 'log_list_pageby'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'log_list_pageby', val = 25"); -} - -if (safe_field("val", 'txp_prefs', "name = 'comment_list_pageby'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'comment_list_pageby', val = 25"); -} - -if (safe_field("val", 'txp_prefs', "name = 'permlink_mode'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'permlink_mode', val = 'section_id_title'"); -} - -if (safe_field("val", 'txp_prefs', "name = 'comments_are_ol'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'comments_are_ol', val = '1'"); -} - -if (safe_field("name", 'txp_prefs', "name = 'path_to_site'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'path_to_site', val = ''"); -} - -// 1.0: need to get non-manually set url-only titles into the textpattern table, -// so we can start using title as an url search option. - -$rs = mysqli_query($DB->link, "SELECT ID, Title FROM `".PFX."textpattern` WHERE url_title LIKE ''"); - -while ($a = mysqli_fetch_array($rs)) { - extract($a); - $url_title = addslashes(stripSpace($Title, 1)); - assert_int($ID); - safe_update('textpattern', "url_title = '$url_title'", "ID = $ID"); -} - -// 1.0: properly i18n. -// Change current language names by language codes. -$lang = fetch("val", 'txp_prefs', 'name', 'language'); - -switch ($lang) { - case 'czech': - $rs = safe_update('txp_prefs', "val = 'cs-cs'", "name = 'language' AND val = 'czech'"); - break; - case 'danish': - $rs = safe_update('txp_prefs', "val = 'da-da'", "name = 'language' AND val = 'danish'"); - break; - case 'dutch': - $rs = safe_update('txp_prefs', "val = 'nl-nl'", "name = 'language' AND val = 'dutch'"); - break; - case 'finish': - $rs = safe_update('txp_prefs', "val = 'fi-fi'", "name = 'language' AND val = 'finish'"); - break; - case 'french': - $rs = safe_update('txp_prefs', "val = 'fr-fr'", "name = 'language' AND val = 'french'"); - break; - case 'german': - $rs = safe_update('txp_prefs', "val = 'de-de'", "name = 'language' AND val = 'german'"); - break; - case 'italian': - $rs = safe_update('txp_prefs', "val = 'it-it'", "name = 'language' AND val = 'italian'"); - break; - case 'polish': - $rs = safe_update('txp_prefs', "val = 'pl-pl'", "name = 'language' AND val = 'polish'"); - break; - case 'portuguese': - $rs = safe_update('txp_prefs', "val = 'pt-pt'", "name = 'language' AND val = 'portuguese'"); - break; - case 'russian': - $rs = safe_update('txp_prefs', "val = 'ru-ru'", "name = 'language' AND val = 'russian'"); - break; - case 'scotts': - //I'm not sure of this one - $rs = safe_update('txp_prefs', "val = 'gl-gl'", "name = 'language' AND val = 'scotts'"); - break; - case 'spanish': - $rs = safe_update('txp_prefs', "val = 'es-es'", "name = 'language' AND val = 'spanish'"); - break; - case 'swedish': - $rs = safe_update('txp_prefs', "val = 'sv-sv'", "name = 'language' AND val = 'swedish'"); - break; - case 'tagalog': - $rs = safe_update('txp_prefs', "val = 'tl-tl'", "name = 'language' AND val = 'tagalog'"); - break; - case 'english': - default: - $rs = safe_update('txp_prefs', "val = 'en-gb'", "name = 'language' AND val = 'english'"); - break; -} - -// 1.0: new time zone offset. -// If we check for a val, and the val is 0, this add another empty one. -if (safe_field("name", 'txp_prefs', "name = 'is_dst'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'is_dst', val = 0"); -} - -// FIXME: this presupposes 'gmtoffset' won't be set at clean install (RC4+ probably will) -if (safe_field("val", 'txp_prefs', "name = 'gmtoffset'") === false) { - $old_offset = safe_field("val", 'txp_prefs', "name = 'timeoffset'"); - $serveroffset = gmmktime(0, 0, 0) - mktime(0, 0, 0); - $gmtoffset = sprintf("%+d", $serveroffset + $old_offset); - safe_insert('txp_prefs', "prefs_id = 1, name = 'gmtoffset', val = '".doSlash($gmtoffset)."'"); -} - -$tempdir = doSlash(find_temp_dir()); - -// 1.0: locale support. -if (safe_field("val", 'txp_prefs', "name = 'locale'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'locale', val = 'en_GB'"); -} - -// 1.0: temp dir. -if (safe_field("val", 'txp_prefs', "name = 'tempdir'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'tempdir', val = '$tempdir'"); -} - -// Non image file upload tab. -if (safe_field("val", 'txp_prefs', "name = 'file_list_pageby'") === false) { - safe_insert('txp_prefs', "val = 25, name = 'file_list_pageby', prefs_id = 1"); -} - -// 1.0: max file upload size. -if (safe_field("val", 'txp_prefs', "name = 'file_max_upload_size'") === false) { - safe_insert('txp_prefs', "prefs_id = 1, name = 'file_max_upload_size', val = 2000000"); -} - -// 1.0: txp_file root cat. -if (!safe_field("name", 'txp_category', "type = 'file' AND name = 'root'")) { - safe_insert('txp_category', "name = 'root', type = 'file', lft = 1, rgt = 0"); -} -rebuild_tree('root', 1, 'file'); - -// 1.0: txp_file folder. -if (safe_field("val", 'txp_prefs', "name = 'file_base_path'") === false) { - safe_insert('txp_prefs', "val = '$tempdir', name = 'file_base_path', prefs_id = 1"); -} - -// 1.0: txp_file table. -safe_create('txp_file', " - id INT NOT NULL AUTO_INCREMENT, - filename VARCHAR(255) NOT NULL DEFAULT '', - category VARCHAR(255) NOT NULL DEFAULT '', - permissions VARCHAR(32) NOT NULL DEFAULT '0', - description TEXT NOT NULL, - downloads INT UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (id), - UNIQUE filename (filename)" -); - -if (safe_field("name", 'txp_form', "type = 'file'") === false) { - safe_insert('txp_form', " - name = 'files', - type = 'file', - Form = ': \n\n []\n\n
\n:
\n: '"); -} -// EOF: non image file upload tab. - -// 1.0: improved comment spam nonce. -$txpnonce = getThings("DESCRIBE `".PFX."txp_discuss_nonce`"); -if (!in_array('secret', $txpnonce)) { - safe_alter('txp_discuss_nonce', "ADD secret VARCHAR(255) NOT NULL DEFAULT ''"); -} - -// 1.0: flag for admin-side plugins. -$txpplugin = getThings("DESCRIBE `".PFX."txp_plugin`"); -if (!in_array('type', $txpplugin)) { - safe_alter('txp_plugin', "ADD type INT NOT NULL DEFAULT '0'"); -} - -// 1.0: log status and method. -$txplog = getThings("DESCRIBE `".PFX."txp_log`"); - -if (!in_array('status', $txplog)) { - safe_alter('txp_log', "ADD status INT NOT NULL DEFAULT '200'"); -} - -if (!in_array('method', $txplog)) { - safe_alter('txp_log', "ADD method VARCHAR(16) NOT NULL DEFAULT 'GET'"); -} - -if (!in_array('ip', $txplog)) { - safe_alter('txp_log', "ADD ip VARCHAR(16) NOT NULL DEFAULT ''"); -} - -// 1.0: need to get Excerpt_html values into the textpattern table, so catch -// empty ones and populate them. -$rs = mysqli_query($DB->link, "SELECT ID, Excerpt, textile_excerpt FROM `".PFX."textpattern` WHERE Excerpt_html LIKE ''"); -$textile = new \Netcarver\Textile\Parser(); - -while ($a = @mysqli_fetch_assoc($rs)) { - extract($a); - assert_int($ID); - $lite = ($textile_excerpt) ? '' : 1; - $Excerpt_html = $textile->textileThis($Excerpt, $lite); - safe_update('textpattern', "Excerpt_html = '".doSlash($Excerpt_html)."'", "ID = $ID"); -} - -// 1.0 feed unique ids. - -// Blog unique id. -if (safe_field("val", 'txp_prefs', "name = 'blog_uid'") === false) { - $prefs['blog_uid'] = md5(uniqid(rand(), true)); - safe_insert('txp_prefs', "name = 'blog_uid', val = '".$prefs['blog_uid']."', prefs_id = '1'"); -} - -if (safe_field("name", 'txp_prefs', "name = 'blog_mail_uid'") === false) { - $mail = safe_field('email', 'txp_users', "privs = '1' LIMIT 1"); - safe_insert('txp_prefs', "name = 'blog_mail_uid', val = '".doSlash($mail)."', prefs_id = '1'"); -} - -if (safe_field("val", 'txp_prefs', "name = 'blog_time_uid'") === false) { - safe_insert('txp_prefs', "name = 'blog_time_uid', val = '".date("Y")."', prefs_id = '1'"); -} - -// Articles unique id. -if (!in_array('uid', $txp)) { - safe_alter('textpattern', "ADD uid VARCHAR(32) NOT NULL"); - safe_alter('textpattern', "ADD feed_time DATE NOT NULL DEFAULT 1970-01-01"); - safe_update('textpattern', "feed_time = DATE(Posted)", "feed_time = '1970-01-01'"); - safe_alter('textpattern', "MODIFY feed_time DATE NOT NULL"); - - $rs = safe_rows_start('ID, Posted', 'textpattern', '1'); - - if ($rs) { - while ($a = nextRow($rs)) { - assert_int($a['ID']); - $feed_time = substr($a['Posted'], 0, 10); - safe_update('textpattern', "uid = '".md5(uniqid(rand(), true))."', feed_time = '".doSlash($feed_time)."'", "ID = {$a['ID']}"); - } - } -} - -// 1.0: populate comments_count field. - -$rs = safe_rows_start("parentid, count(*) AS thecount", 'txp_discuss', "visible = 1 GROUP BY parentid"); - -if ($rs) { - while ($a = nextRow($rs)) { - assert_int($a['parentid']); - safe_update('textpattern', "comments_count = ".$a['thecount'], "ID = ".$a['parentid']); - } -} - -// 1.0: Human-friendly title for sections and categories, to solve i18n problems. -if (!in_array('title', $txpsect)) { - safe_alter('txp_section', "ADD title VARCHAR(255) NOT NULL DEFAULT ''"); -} - -if (!in_array('title', $txpcat)) { - safe_alter('txp_category', "ADD title VARCHAR(255) NOT NULL DEFAULT ''"); -} - -if (safe_count('txp_section', "title = ''") > 0) { - safe_update('txp_section', "title = name", "title = ''"); -} - -if (safe_count('txp_category', "title = ''") > 0) { - safe_update('txp_category', "title = name", "title = ''"); -} - -// 1.0: Unique key and 'type' field for the txp_prefs table. -safe_create_index('txp_prefs', 'prefs_id, name', 'prefs_idx', 'unique'); - -$txpprefs = getThings('DESCRIBE `'.PFX.'txp_prefs`'); - -if (!in_array('type', $txpprefs)) { - safe_alter('txp_prefs', "ADD type SMALLINT UNSIGNED NOT NULL DEFAULT '2'"); -} - -// Update the updated with default hidden type for old plugins prefs. -safe_alter('txp_prefs', "MODIFY type SMALLINT UNSIGNED NOT NULL DEFAULT '2'"); - -if (!in_array('event', $txpprefs)) { - safe_alter('txp_prefs', "ADD event VARCHAR(12) NOT NULL DEFAULT 'publish'"); -} - -if (!in_array('html', $txpprefs)) { - safe_alter('txp_prefs', "ADD html VARCHAR(64) NOT NULL DEFAULT ''"); -} - -if (!in_array('position', $txpprefs)) { - safe_alter('txp_prefs', "ADD position SMALLINT UNSIGNED NOT NULL DEFAULT '0'"); - - // Add new column values to prefs. - $prefs_new_cols = array( - 'attach_titles_to_permalinks' => array('html' => 'yesnoradio', 'event' => 'publish', 'type' => '1', 'position' => '1'), - 'sitename' => array('html' => 'text_input', 'event' => 'publish', 'type' => '0', 'position' => '1'), - 'siteurl' => array('html' => 'text_input', 'event' => 'publish', 'type' => '0', 'position' => '2'), - 'site_slogan' => array('html' => 'text_input', 'event' => 'publish', 'type' => '0', 'position' => '3'), - 'language' => array('html' => 'languages', 'event' => 'publish', 'type' => '0', 'position' => '4'), - 'gmtoffset' => array('html' => 'gmtoffset_select', 'event' => 'publish', 'type' => '0', 'position' => '5'), - 'is_dst' => array('html' => 'yesnoradio', 'event' => 'publish', 'type' => '0', 'position' => '6'), - 'dateformat' => array('html' => 'dateformats', 'event' => 'publish', 'type' => '0', 'position' => '7'), - 'archive_dateformat' => array('html' => 'dateformats', 'event' => 'publish', 'type' => '0', 'position' => '8'), - 'permlink_mode' => array('html' => 'permlinkmodes', 'event' => 'publish', 'type' => '0', 'position' => '9'), - 'send_lastmod' => array('html' => 'yesnoradio', 'event' => 'admin', 'type' => '1', 'position' => '0'), - 'ping_weblogsdotcom' => array('html' => 'yesnoradio', 'event' => 'publish', 'type' => '1', 'position' => '0'), - 'use_comments' => array('html' => 'yesnoradio', 'event' => 'publish', 'type' => '0', 'position' => '12'), - 'logging' => array('html' => 'logging', 'event' => 'publish', 'type' => '0', 'position' => '10'), - 'use_textile' => array('html' => 'pref_text', 'event' => 'publish', 'type' => '0', 'position' => '11'), - 'tempdir' => array('html' => 'text_input', 'event' => 'admin', 'type' => '1', 'position' => '0'), - 'file_base_path' => array('html' => 'text_input', 'event' => 'admin', 'type' => '1', 'position' => '0'), - 'file_max_upload_size' => array('html' => 'text_input', 'event' => 'admin', 'type' => '1', 'position' => '0'), - 'comments_moderate' => array('html' => 'yesnoradio', 'event' => 'comments', 'type' => '0', 'position' => '13'), - 'comments_on_default' => array('html' => 'yesnoradio', 'event' => 'comments', 'type' => '0', 'position' => '14'), - 'comments_are_ol' => array('html' => 'yesnoradio', 'event' => 'comments', 'type' => '0', 'position' => '15'), - 'comments_sendmail' => array('html' => 'yesnoradio', 'event' => 'comments', 'type' => '0', 'position' => '16'), - 'comments_disallow_images' => array('html' => 'yesnoradio', 'event' => 'comments', 'type' => '0', 'position' => '17'), - 'comments_default_invite' => array('html' => 'text_input', 'event' => 'comments', 'type' => '0', 'position' => '18'), - 'comments_dateformat' => array('html' => 'dateformats', 'event' => 'comments', 'type' => '0', 'position' => '19'), - 'comments_mode' => array('html' => 'commentmode', 'event' => 'comments', 'type' => '0', 'position' => '20'), - 'comments_disabled_after' => array('html' => 'weeks', 'event' => 'comments', 'type' => '0', 'position' => '21'), - 'img_dir' => array('html' => 'text_input', 'event' => 'admin', 'type' => '1', 'position' => '0'), - 'rss_how_many' => array('html' => 'text_input', 'event' => 'admin', 'type' => '1', 'position' => '0'), - ); - - foreach ($prefs_new_cols as $pref_key => $pref_val) { - safe_update('txp_prefs', "html = '$pref_val[html]', event = '$pref_val[event]', type = '$pref_val[type]', position = '$pref_val[position]'", "name = '$pref_key' AND prefs_id = '1'"); - } - - $prefs_hidden_rows = array('prefs_id', 'use_categories', 'use_sections', 'path_from_root', 'url_mode', 'record_mentions', - 'locale', 'file_base_path', 'lastmod', 'version', 'path_to_site', 'dbupdatetime', 'timeoffset', 'article_list_pageby', - 'blog_mail_uid', 'blog_time_uid', 'blog_uid', 'comment_list_pageby', 'file_list_pageby', 'image_list_pageby', 'link_list_pageby', - 'log_list_pageby',); - - foreach ($prefs_hidden_rows as $hidden_pref) { - safe_update('txp_prefs', "type = '2'", "name = '$hidden_pref' AND prefs_id = '1'"); - } - - global $txpac; - - // Advanced prefs. - foreach ($txpac as $key => $val) { - if (!in_array($key, array_keys($prefs))) { - switch ($key) { - case 'custom_1_set': - case 'custom_2_set': - case 'custom_3_set': - case 'custom_4_set': - case 'custom_5_set': - case 'custom_6_set': - case 'custom_7_set': - case 'custom_8_set': - case 'custom_9_set': - case 'custom_10_set': - $evt = 'custom'; - $html = 'text_input'; - break; - case 'edit_raw_css_by_default': - $evt = 'css'; - $html = 'yesnoradio'; - break; - case 'spam_blacklists': - case 'expire_logs_after': - case 'max_url_len': - $html = 'text_input'; - $evt = 'publish'; - break; - case 'textile_links': - $html = 'yesnoradio'; - $evt = 'link'; - break; - case 'show_article_category_count': - $html = 'yesnoradio'; - $evt = 'category'; - break; - case 'comments_require_name': - case 'comments_require_email': - $html = 'yesnoradio'; - $evt = 'comments'; - break; - default: - $html = 'yesnoradio'; - $evt = 'publish'; - break; - } - safe_insert('txp_prefs', "val = '$val', name = '$key' , prefs_id = '1', type = '1', html = '$html', event = '$evt'"); - } - } -} - -safe_alter('txp_prefs', "MODIFY html VARCHAR(64) DEFAULT 'text_input' NOT NULL"); -safe_update('txp_prefs', "html = 'text_input'", "html = ''"); - -if (!fetch("form", 'txp_form', 'name', 'search_results')) { - $form = << -


- · -

-EOF; - safe_insert('txp_form', "name = 'search_results', type = 'article', Form = '".doSlash($form)."'"); -} - -if (!safe_query("SELECT 1 FROM `".PFX."txp_lang` LIMIT 0")) { - // Do install. - safe_query("CREATE TABLE `".PFX."txp_lang` ( - id INT NOT NULL AUTO_INCREMENT, - lang VARCHAR(16) NOT NULL, - name VARCHAR(64) NOT NULL, - event VARCHAR(64) NOT NULL, - data TINYTEXT, - lastmod TIMESTAMP, - PRIMARY KEY (id), - UNIQUE lang (lang, name), - INDEX lang_2 (lang, event) - ) $tabletype "); - - require_once txpath.'/lib/IXRClass.php'; - - $client = new IXR_Client('http://rpc.textpattern.com'); - - if (!$client->query('tups.getLanguage', $prefs['blog_uid'], LANG)) { - echo '

Error trying to install language. Please, try it again again.
- If problem connecting to the RPC server persists, you can go to http://rpc.textpattern.com/lang/, download the - desired language file and place it in the /lang/ directory of your textpattern install. You can then install the language from file.

'; - } else { - $response = $client->getResponse(); - $lang_struct = unserialize($response); - - function install_lang_key($value, $key) - { - $q = "name = '".doSlash($value[name])."', event = '".doSlash($value[event])."', data = '".doSlash($value[data])."', lastmod = '".doSlash(strftime('%Y%m%d%H%M%S', $value['uLastmod']))."'"; - safe_insert('txp_lang', $q.", lang = '".LANG."'"); - } - - array_walk($lang_struct, 'install_lang_key'); - } -} - -$maxpos = safe_field("MAX(position)", 'txp_prefs', "1 = 1"); - -// 1.0: production_status setting to control error reporting. -if (safe_field("val", 'txp_prefs', "name = 'production_status'") === false) { - safe_insert('txp_prefs', "name = 'production_status', val = 'testing', prefs_id = '1', type = '0', position = '".doSlash($maxpos)."', html = 'prod_levels'"); -} - -// Multiply position on prefs to allow easy reordering. -if (intval($maxpos) < 100) { - safe_update('txp_prefs', "position = position * 10", "1 = 1"); -} - -// Remove, remove. -if (safe_field("name", 'txp_prefs', "name = 'logs_expire'") !== false) { - safe_delete('txp_prefs', "name = 'logs_expire'"); -} - -// Let's make this visible in advanced prefs. -safe_update('txp_prefs', "type = '1'", "name = 'file_base_path'"); - -// 1.0: add option to override charset for emails (ISO-8559-1 instead of UTF-8). -if (safe_field("name", 'txp_prefs', "name = 'override_emailcharset'") === false) { - safe_insert('txp_prefs', "name = 'override_emailcharset', val = '0', prefs_id = '1', type = '1', event = 'admin', position = '".doSlash($maxpos)."', html = 'yesnoradio'"); -} - -if (safe_field("val", 'txp_prefs', "name = 'comments_auto_append'") === false) { - safe_insert('txp_prefs', "val = '1', name = 'comments_auto_append' , prefs_id = '1', type = '0', html = 'yesnoradio', event = 'comments', position = '211'"); - - if (safe_field("name", 'txp_form', "name = 'comments_display'") === false) { - $form = << - - - -EOF; - safe_insert('txp_form', "name = 'comments_display', type = 'article', Form = '".doSlash($form)."'"); - } -} - -// /tmp is bad for permanent storage of files, if no files are uploaded yet, -// switch to the files directory in the top-txp dir. -if (!safe_count('txp_file', "1")) { - $tempdir = find_temp_dir(); - - if ($tempdir === safe_field("val", 'txp_prefs', "name = 'file_base_path'")) { - safe_update('txp_prefs', "val = '".doSlash(dirname(txpath).DS.'files')."', prefs_id = 1", "name = 'file_base_path'"); - } -} - -// After this point the changes after RC4. - -// Let's get the advanced fields in the right order. -for ($i = 1; $i <= 10; $i++) { - safe_update('txp_prefs', "position = $i", "name = 'custom_${i}_set'"); -} - -// Index ip column in txp_log. -safe_create_index('txp_log', 'ip', 'ip'); - -// Language selection moves to Manage languages, Hide it from prefs. -safe_update('txp_prefs', "type = 2", "name = 'language'"); - -// Show gmt-selection in prefs. -safe_update('txp_prefs', "type = 0, html = 'gmtoffset_select', position = 50", "name = 'gmtoffset'"); - -if (safe_field("name", 'txp_prefs', "prefs_id = 1 AND name = 'plugin_cache_dir'") === false) { - $maxpos = safe_field("MAX(position)", 'txp_prefs', "1 = 1"); - safe_insert('txp_prefs', "name = 'plugin_cache_dir', val = '', prefs_id = '1', type = '1', event = 'admin', position = '".doSlash($maxpos)."', html = 'text_input'"); -} - -// Update version. -safe_delete('txp_prefs', "name = 'version'"); -safe_insert('txp_prefs', "prefs_id = 1, name = 'version', val = '4.0', type = '2'"); diff --git a/textpattern/update/_to_4.0.2.php b/textpattern/update/_to_4.0.2.php deleted file mode 100644 index c55571a95c..0000000000 --- a/textpattern/update/_to_4.0.2.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -if (!defined('TXP_UPDATE')) { - exit("Nothing here. You can't access this file directly."); -} - -if (!safe_field("name", 'txp_page', "name = 'error_default'")) { - $error_default = "\n\n\n\t\n\n\t<txp:site_name />: <txp:error_status />\n\n\t\" />\n\n\t\n\t\n\n\t\n\n\n\n\n
\n\t
    \n\t\t
  • \n\t\t
  • \n\t\t
  • \n\t
\n
\n\n
\n\n\n\t
\n\t\t

\n\t\t

\n\t
\n\n\n\t
\n\t\t\' include_default=\"1\" wraptag=\"ul\" break=\"li\">\n\t\t\t\'>»\n\t\t\t\n\t\t\t\'>\n\t\t\t\t\' wraptag=\"ul\" break=\"li\">\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\n\t\t\n\n\t\t

/

\n\t
\n\n\n\t\n\n\n\t
\n\t\t

\n\t\t

\n\t
\n\n\n\t
 
\n\n
\n\n\n"; - safe_insert('txp_page', " name = 'error_default', user_html = '".doSlash($error_default)."'"); -} - -// Take back use_textile. -safe_update('txp_prefs', "html = 'pref_text'", "name = 'use_textile'"); - -// Ugly way to change somethign which could break BC: changed use_textile == 2 -// to convert breaks and use_textile == 1 to use textile - the same than in -// textile_body or textile_excerpt. -if (safe_field("val", 'txp_prefs', "name = 'textile_updated'") === false) { - $ut = safe_field("val", 'txp_prefs', "name = 'use_textile'"); - - if ($ut == 1) { - safe_update('txp_prefs', "val = '2'", "name = 'use_textile'"); - } elseif ($ut == 2) { - safe_update('txp_prefs', "val = '1'", "name = 'use_textile'"); - } - - safe_insert('txp_prefs', "prefs_id = 1, name = 'textile_updated', val = '1', type = '2'"); -} diff --git a/textpattern/vendors/Textpattern/Http/Request.php b/textpattern/vendors/Textpattern/Http/Request.php index fc237b7314..49ece460a0 100644 --- a/textpattern/vendors/Textpattern/Http/Request.php +++ b/textpattern/vendors/Textpattern/Http/Request.php @@ -520,12 +520,6 @@ public function getHeaders() return $this->headers; } - if (function_exists('apache_request_headers')) { - if ($this->headers = apache_request_headers()) { - return $this->headers; - } - } - $this->headers = array(); foreach ($_SERVER as $name => $value) { diff --git a/textpattern/vendors/dropbox/zxcvbn/zxcvbn.js b/textpattern/vendors/dropbox/zxcvbn/zxcvbn.js index 9ee1fa1693..0daf83098e 100755 --- a/textpattern/vendors/dropbox/zxcvbn/zxcvbn.js +++ b/textpattern/vendors/dropbox/zxcvbn/zxcvbn.js @@ -18,7 +18,7 @@ var feedback,matching,scoring,time,time_estimates,zxcvbn;matching=require("./mat var DATE_MAX_YEAR,DATE_MIN_YEAR,DATE_SPLITS,GRAPHS,L33T_TABLE,RANKED_DICTIONARIES,REGEXEN,adjacency_graphs,build_ranked_dict,frequency_lists,lst,matching,name,scoring;frequency_lists=require("./frequency_lists"),adjacency_graphs=require("./adjacency_graphs"),scoring=require("./scoring"),build_ranked_dict=function(e){var t,n,r,i,a;for(i={},t=1,r=0,n=e.length;r_;r=0<=_?++o:--o)for(i=h=f=r,d=a;f<=d?hd;i=f<=d?++h:--h)u.slice(r,+i+1||9e9)in l&&(p=u.slice(r,+i+1||9e9),c=l[p],s.push({pattern:"dictionary",i:r,j:i,token:e.slice(r,+i+1||9e9),matched_word:p,rank:c,dictionary_name:n,reversed:!1,l33t:!1}));return this.sorted(s)},reverse_dictionary_match:function(e,t){var n,r,i,a,s,o;for(null==t&&(t=RANKED_DICTIONARIES),o=e.split("").reverse().join(""),i=this.dictionary_match(o,t),a=0,n=i.length;a0&&(l[i]=h);return l},enumerate_l33t_subs:function(e){var t,n,r,i,a,s,o,h,u,c,l,_,f,d,p;a=function(){var t;t=[];for(i in e)t.push(i);return t}(),p=[[]],n=function(e){var t,n,r,a,s,o,h,u;for(n=[],s={},o=0,a=e.length;og;s=0<=g?++f:--f)if(A[s][0]===o){i=s;break}i===-1?(y=A.concat([[o,a]]),c.push(y)):(E=A.slice(0),E.splice(i,1),E.push([o,a]),c.push(A),c.push(E))}return p=n(c),r(m)}},r(a),d=[];for(u=0,o=p.length;u "+A);return e}().join(", "),u.push(o)}return this.sorted(u.filter(function(e){return e.token.length>1}))},spatial_match:function(e,t){var n,r,i;null==t&&(t=GRAPHS),i=[];for(r in t)n=t[r],this.extend(i,this.spatial_match_helper(e,n,r));return this.sorted(i)},SHIFTED_RX:/[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?]/,spatial_match_helper:function(e,t,n){var r,i,a,s,o,h,u,c,l,_,f,d,p,g,m;for(f=[],u=0;u2&&f.push({pattern:"spatial",i:u,j:c-1,token:e.slice(u,c),graph:n,turns:m,shifted_count:g}),u=c;break}c+=1}return f},repeat_match:function(e){var t,n,r,i,a,s,o,h,u,c,l,_,f,d,p;for(d=[],a=/(.+)\1+/g,c=/(.+?)\1+/g,l=/^(.+?)\1+$/,u=0;u_[0].length?(f=s,i=l.exec(f[0])[1]):(f=_,i=f[1]),p=[f.index,f.index+f[0].length-1],o=p[0],h=p[1],t=scoring.most_guessable_match_sequence(i,this.omnimatch(i)),r=t.sequence,n=t.guesses,d.push({pattern:"repeat",i:o,j:h,token:f[0],base_token:i,base_guesses:n,base_matches:r,repeat_count:f[0].length/i.length}),u=h+1;return d},MAX_DELTA:5,sequence_match:function(e){var t,n,r,i,a,s,o,h,u;if(1===e.length)return[];for(u=function(t){return function(n,r,i){var a,s,o,u;if((r-n>1||1===Math.abs(i))&&0<(a=Math.abs(i))&&a<=t.MAX_DELTA)return u=e.slice(n,+r+1||9e9),/^[a-z]+$/.test(u)?(s="lower",o=26):/^[A-Z]+$/.test(u)?(s="upper",o=26):/^\d+$/.test(u)?(s="digits",o=10):(s="unicode",o=26),h.push({pattern:"sequence",i:n,j:r,token:e.slice(n,+r+1||9e9),sequence_name:s,sequence_space:o,ascending:i>0})}}(this),h=[],n=0,a=null,i=s=1,o=e.length;1<=o?so;i=1<=o?++s:--s)t=e.charCodeAt(i)-e.charCodeAt(i-1),null==a&&(a=t),t!==a&&(r=i-1,u(n,r,a),n=r,a=t);return u(n,e.length-1,a),h},regex_match:function(e,t){var n,r,i,a;null==t&&(t=REGEXEN),n=[];for(name in t)for(r=t[name],r.lastIndex=0;i=r.exec(e);)a=i[0],n.push({pattern:"regex",token:a,i:i.index,j:i.index+i[0].length-1,regex_name:name,regex_match:i});return this.sorted(n)},date_match:function(e){var t,n,r,i,a,s,o,h,u,c,l,_,f,d,p,g,m,A,E,y,v,I,R,T,D,k,x,j,b,N,S,q,L,M;for(_=[],f=/^\d{4,8}$/,d=/^(\d{1,4})([\s\/\\_.-])(\d{1,2})\2(\d{1,4})$/,s=m=0,v=e.length-4;0<=v?m<=v:m>=v;s=0<=v?++m:--m)for(o=A=I=s+3,R=s+7;(I<=R?A<=R:A>=R)&&!(o>=e.length);o=I<=R?++A:--A)if(M=e.slice(s,+o+1||9e9),f.exec(M)){for(r=[],T=DATE_SPLITS[M.length],E=0,c=T.length;E0){for(t=r[0],p=function(e){return Math.abs(e.year-scoring.REFERENCE_YEAR)},g=p(r[0]),k=r.slice(1),y=0,l=k.length;y=j;s=0<=j?++q:--q)for(o=L=b=s+5,N=s+9;(b<=N?L<=N:L>=N)&&!(o>=e.length);o=b<=N?++L:--L)M=e.slice(s,+o+1||9e9),S=d.exec(M),null!=S&&(a=this.map_ints_to_dmy([parseInt(S[1]),parseInt(S[3]),parseInt(S[4])]),null!=a&&_.push({pattern:"date",token:M,i:s,j:o,separator:S[2],year:a.year,month:a.month,day:a.day}));return this.sorted(_.filter(function(e){var t,n,r,i;for(t=!1,i=0,n=_.length;i=e.j){t=!0;break}return!t}))},map_ints_to_dmy:function(e){var t,n,r,i,a,s,o,h,u,c,l,_,f,d,p,g;if(!(e[1]>31||e[1]<=0)){for(o=0,h=0,p=0,s=0,r=e.length;sDATE_MAX_YEAR)return;n>31&&(h+=1),n>12&&(o+=1),n<=0&&(p+=1)}if(!(h>=2||3===o||p>=2)){for(c=[[e[2],e.slice(0,2)],[e[0],e.slice(1,3)]],u=0,i=c.length;u99?e:e>50?e+1900:e+2e3}},module.exports=matching; },{"./adjacency_graphs":1,"./frequency_lists":3,"./scoring":6}],6:[function(require,module,exports){ -var BRUTEFORCE_CARDINALITY,MIN_GUESSES_BEFORE_GROWING_SEQUENCE,MIN_SUBMATCH_GUESSES_MULTI_CHAR,MIN_SUBMATCH_GUESSES_SINGLE_CHAR,adjacency_graphs,calc_average_degree,k,scoring,v;adjacency_graphs=require("./adjacency_graphs"),calc_average_degree=function(e){var t,r,n,s,a,i;t=0;for(n in e)a=e[n],t+=function(){var e,t,r;for(r=[],t=0,e=a.length;te)return 0;if(0===t)return 1;for(s=1,r=n=1,a=t;1<=a?n<=a:n>=a;r=1<=a?++n:--n)s*=e,s/=r,e-=1;return s},log10:function(e){return Math.log(e)/Math.log(10)},log2:function(e){return Math.log(e)/Math.log(2)},factorial:function(e){var t,r,n,s;if(e<2)return 1;for(t=1,r=n=2,s=e;2<=s?n<=s:n>=s;r=2<=s?++n:--n)t*=r;return t},most_guessable_match_sequence:function(e,t,r){var n,s,a,i,u,_,o,h,E,c,g,f,l,p,A,S,R,v,I,M,N,C,U,T;for(null==r&&(r=!1),l=e.length,f=function(){var e,t,r;for(r=[],n=e=0,t=l;0<=t?et;n=0<=t?++e:--e)r.push([]);return r}(),p=0,_=t.length;p<_;p++)c=t[p],f[c.j].push(c);for(v=0,o=f.length;ve;n=0<=e?++r:--r)t.push({});return t}(),pi:function(){var e,t,r;for(t=[],n=r=0,e=l;0<=e?re;n=0<=e?++r:--r)t.push({});return t}(),g:function(){var e,t,r;for(t=[],n=r=0,e=l;0<=e?re;n=0<=e?++r:--r)t.push({});return t}()},U=function(t){return function(n,s){var a,i,u,_,o,h;_=n.j,o=t.estimate_guesses(n,e),s>1&&(o*=A.pi[n.i-1][s-1]),u=t.factorial(s)*o,r||(u+=Math.pow(MIN_GUESSES_BEFORE_GROWING_SEQUENCE,s-1)),h=A.g[_];for(i in h)if(a=h[i],!(i>s)&&a<=u)return;return A.g[_][s]=u,A.m[_][s]=n,A.pi[_][s]=o}}(this),s=function(e){return function(e){var t,r,n,s;if(c=g(0,e),U(c,1),0!==e){n=A.m[e-1],s=[];for(t in n)r=n[t],t=parseInt(t),"bruteforce"===r.pattern?(c=g(r.i,e),s.push(U(c,t))):(c=g(e,e),s.push(U(c,t+1)));return s}}}(this),g=function(t){return function(t,r){return{pattern:"bruteforce",token:e.slice(t,+r+1||9e9),i:t,j:r}}}(this),C=function(e){return function(e){var t,r,n,s,a,i,u;i=[],s=e-1,a=void 0,n=1/0,u=A.g[s];for(r in u)t=u[r],t=0;)c=A.m[s][a],i.unshift(c),s=c.i-1,a--;return i}}(this),i=N=0,I=l;0<=I?NI;i=0<=I?++N:--N){for(M=f[i],T=0,h=M.length;T0)for(u in A.m[c.i-1])u=parseInt(u),U(c,u+1);else U(c,1);s(i)}return R=C(l),S=R.length,a=0===e.length?1:A.g[l-1][S],{password:e,guesses:a,guesses_log10:this.log10(a),sequence:R}},estimate_guesses:function(e,t){var r,n,s;return null!=e.guesses?e.guesses:(s=1,e.token.length=c;i=2<=c?++_:--_)for(o=Math.min(A,i-1),u=h=1,g=o;1<=g?h<=g:h>=g;u=1<=g?++h:--h)a+=this.nCk(i-1,u-1)*l*Math.pow(s,u);if(e.shifted_count)if(r=e.shifted_count,n=e.token.length-e.shifted_count,0===r||0===n)a*=2;else{for(p=0,i=S=1,f=Math.min(r,n);1<=f?S<=f:S>=f;i=1<=f?++S:--S)p+=this.nCk(r+n,i);a*=p}return a},dictionary_guesses:function(e){var t;return e.base_guesses=e.rank,e.uppercase_variations=this.uppercase_variations(e),e.l33t_variations=this.l33t_variations(e),t=e.reversed&&2||1,e.base_guesses*e.uppercase_variations*e.l33t_variations*t},START_UPPER:/^[A-Z][^A-Z]+$/,END_UPPER:/^[^A-Z]+[A-Z]$/,ALL_UPPER:/^[^a-z]+$/,ALL_LOWER:/^[^A-Z]+$/,uppercase_variations:function(e){var t,r,n,s,a,i,u,_,o,h,E,c;if(c=e.token,c.match(this.ALL_LOWER)||c.toLowerCase()===c)return 1;for(_=[this.START_UPPER,this.END_UPPER,this.ALL_UPPER],i=0,a=_.length;i=o;s=1<=o?++u:--u)E+=this.nCk(r+t,s);return E},l33t_variations:function(e){var t,r,n,s,a,i,u,_,o,h,E,c,g;if(!e.l33t)return 1;g=1,o=e.sub;for(E in o)if(c=o[E],s=e.token.toLowerCase().split(""),t=function(){var e,t,r;for(r=[],t=0,e=s.length;t=h;a=1<=h?++i:--i)_+=this.nCk(r+t,a);g*=_}return g}},module.exports=scoring; +var BRUTEFORCE_CARDINALITY,MIN_GUESSES_BEFORE_GROWING_SEQUENCE,MIN_SUBMATCH_GUESSES_MULTI_CHAR,MIN_SUBMATCH_GUESSES_SINGLE_CHAR,adjacency_graphs,calc_average_degree,k,scoring,v;adjacency_graphs=require("./adjacency_graphs"),calc_average_degree=function(e){var t,r,n,s,a,u;t=0;for(n in e)a=e[n],t+=function(){var e,t,r;for(r=[],t=0,e=a.length;te)return 0;if(0===t)return 1;for(s=1,r=n=1,a=t;1<=a?n<=a:n>=a;r=1<=a?++n:--n)s*=e,s/=r,e-=1;return s},log10:function(e){return Math.log(e)/Math.log(10)},log2:function(e){return Math.log(e)/Math.log(2)},factorial:function(e){var t,r,n,s;if(e<2)return 1;for(t=1,r=n=2,s=e;2<=s?n<=s:n>=s;r=2<=s?++n:--n)t*=r;return t},most_guessable_match_sequence:function(e,t,r){var n,s,a,u,i,_,o,h,E,c,g,f,l,p,A,S,R,v,I,M,N,C,U,T;for(null==r&&(r=!1),l=e.length,f=function(){var e,t,r;for(r=[],n=e=0,t=l;0<=t?et;n=0<=t?++e:--e)r.push([]);return r}(),p=0,_=t.length;p<_;p++)c=t[p],f[c.j].push(c);for(v=0,o=f.length;ve;n=0<=e?++r:--r)t.push({});return t}(),pi:function(){var e,t,r;for(t=[],n=r=0,e=l;0<=e?re;n=0<=e?++r:--r)t.push({});return t}(),g:function(){var e,t,r;for(t=[],n=r=0,e=l;0<=e?re;n=0<=e?++r:--r)t.push({});return t}()},U=function(t){return function(n,s){var a,u,i,_,o,h;_=n.j,o=t.estimate_guesses(n,e),s>1&&(o*=A.pi[n.i-1][s-1]),i=t.factorial(s)*o,r||(i+=Math.pow(MIN_GUESSES_BEFORE_GROWING_SEQUENCE,s-1)),h=A.g[_];for(u in h)if(a=h[u],!(u>s)&&a<=i)return;return A.g[_][s]=i,A.m[_][s]=n,A.pi[_][s]=o}}(this),s=function(e){return function(e){var t,r,n,s,a,u;for(c=g(0,e),U(c,1),a=[],t=u=1,s=e;1<=s?u<=s:u>=s;t=1<=s?++u:--u)c=g(t,e),a.push(function(){var e,s;e=A.m[t-1],s=[];for(r in e)n=e[r],r=parseInt(r),"bruteforce"!==n.pattern&&s.push(U(c,r+1));return s}());return a}}(this),g=function(t){return function(t,r){return{pattern:"bruteforce",token:e.slice(t,+r+1||9e9),i:t,j:r}}}(this),C=function(e){return function(e){var t,r,n,s,a,u,i;u=[],s=e-1,a=void 0,n=1/0,i=A.g[s];for(r in i)t=i[r],t=0;)c=A.m[s][a],u.unshift(c),s=c.i-1,a--;return u}}(this),u=N=0,I=l;0<=I?NI;u=0<=I?++N:--N){for(M=f[u],T=0,h=M.length;T0)for(i in A.m[c.i-1])i=parseInt(i),U(c,i+1);else U(c,1);s(u)}return R=C(l),S=R.length,a=0===e.length?1:A.g[l-1][S],{password:e,guesses:a,guesses_log10:this.log10(a),sequence:R}},estimate_guesses:function(e,t){var r,n,s;return null!=e.guesses?e.guesses:(s=1,e.token.length=c;u=2<=c?++_:--_)for(o=Math.min(A,u-1),i=h=1,g=o;1<=g?h<=g:h>=g;i=1<=g?++h:--h)a+=this.nCk(u-1,i-1)*l*Math.pow(s,i);if(e.shifted_count)if(r=e.shifted_count,n=e.token.length-e.shifted_count,0===r||0===n)a*=2;else{for(p=0,u=S=1,f=Math.min(r,n);1<=f?S<=f:S>=f;u=1<=f?++S:--S)p+=this.nCk(r+n,u);a*=p}return a},dictionary_guesses:function(e){var t;return e.base_guesses=e.rank,e.uppercase_variations=this.uppercase_variations(e),e.l33t_variations=this.l33t_variations(e),t=e.reversed&&2||1,e.base_guesses*e.uppercase_variations*e.l33t_variations*t},START_UPPER:/^[A-Z][^A-Z]+$/,END_UPPER:/^[^A-Z]+[A-Z]$/,ALL_UPPER:/^[^a-z]+$/,ALL_LOWER:/^[^A-Z]+$/,uppercase_variations:function(e){var t,r,n,s,a,u,i,_,o,h,E,c;if(c=e.token,c.match(this.ALL_LOWER)||c.toLowerCase()===c)return 1;for(_=[this.START_UPPER,this.END_UPPER,this.ALL_UPPER],u=0,a=_.length;u=o;s=1<=o?++i:--i)E+=this.nCk(r+t,s);return E},l33t_variations:function(e){var t,r,n,s,a,u,i,_,o,h,E,c,g;if(!e.l33t)return 1;g=1,o=e.sub;for(E in o)if(c=o[E],s=e.token.toLowerCase().split(""),t=function(){var e,t,r;for(r=[],t=0,e=s.length;t=h;a=1<=h?++u:--u)_+=this.nCk(r+t,a);g*=_}return g}},module.exports=scoring; },{"./adjacency_graphs":1}],7:[function(require,module,exports){ var time_estimates;time_estimates={estimate_attack_times:function(e){var t,n,s,o;n={online_throttling_100_per_hour:e/(100/3600),online_no_throttling_10_per_second:e/10,offline_slow_hashing_1e4_per_second:e/1e4,offline_fast_hashing_1e10_per_second:e/1e10},t={};for(s in n)o=n[s],t[s]=this.display_time(o);return{crack_times_seconds:n,crack_times_display:t,score:this.guesses_to_score(e)}},guesses_to_score:function(e){var t;return t=5,e<1e3+t?0:e<1e6+t?1:e<1e8+t?2:e<1e10+t?3:4},display_time:function(e){var t,n,s,o,_,r,i,a,u,c;return i=60,r=60*i,s=24*r,a=31*s,c=12*a,n=100*c,u=e<1?[null,"less than a second"]:e