diff --git a/composer.json b/composer.json
index 07525ef..6cf7a86 100644
--- a/composer.json
+++ b/composer.json
@@ -15,7 +15,8 @@
"system/includes/functions.php",
"system/admin/admin.php",
"system/includes/session.php",
- "system/includes/opml.php"
+ "system/includes/opml.php",
+ "system/plugins/urlify/URLify.php"
]
}
}
diff --git a/composer.lock b/composer.lock
index 0cb0e2d..5cdfd99 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "8fa115690163d74447e69c8ab719948b",
+ "hash": "40c7e6fec1121162c6d2243840450628",
"content-hash": "e98ae62bcc711211dfb7c7c70e7fdfc7",
"packages": [
{
diff --git a/system/admin/admin.php b/system/admin/admin.php
index d68f9d6..2dee18e 100644
--- a/system/admin/admin.php
+++ b/system/admin/admin.php
@@ -78,13 +78,7 @@ function old_password_verify($pass, $user_enc, $user_pass)
// Clean URLs
function remove_accent($str)
{
- $a = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
- $b = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
- $cyr = array('ж', 'ч', 'щ', 'ш', 'ю', 'а', 'б', 'в', 'г', 'д', 'e', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ъ', 'ь', 'я', 'Ж', 'Ч', 'Щ', 'Ш', 'Ю', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ъ', 'Ь', 'Я');
- $lat = array('zh', 'ch', 'sht', 'sh', 'yu', 'a', 'b', 'v', 'g', 'd', 'e', 'z', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'y', 'x', 'q', 'Zh', 'Ch', 'Sht', 'Sh', 'Yu', 'A', 'B', 'V', 'G', 'D', 'E', 'Z', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'c', 'Y', 'X', 'Q');
- $a = array_merge($a, $cyr);
- $b = array_merge($b, $lat);
- return str_replace($a, $b, $str);
+ return URLify::downcode($str);
}
// Edit blog posts
diff --git a/system/htmly.php b/system/htmly.php
index a94710d..5ad493c 100644
--- a/system/htmly.php
+++ b/system/htmly.php
@@ -1564,6 +1564,9 @@ get('/tag/:tag', function ($tag) {
$posts = get_tag($tag, $page, $perpage, false);
$total = get_tagcount($tag, 'basename');
+
+ $ttag = new stdClass;
+ $ttag->title = tag_i18n($tag);
if (empty($posts) || $page < 1) {
// a non-existing page
@@ -1575,6 +1578,7 @@ get('/tag/:tag', function ($tag) {
'canonical' => site_url() . 'tag/' . strtolower($tag),
'page' => $page,
'posts' => $posts,
+ 'tag' => $ttag,
'bodyclass' => 'intag',
'breadcrumb' => '' . config('breadcrumb.home') . ' » Posts tagged: ' . tag_i18n($tag),
'pagination' => has_pagination($total, $perpage, $page),
@@ -1612,6 +1616,9 @@ get('/archive/:req', function ($req) {
} else {
$timestamp = $req;
}
+
+ $tarchive = new stdClass;
+ $tarchive->title = $timestamp;
if (!$date) {
// a non-existing page
@@ -1624,6 +1631,7 @@ get('/archive/:req', function ($req) {
'canonical' => site_url() . 'archive/' . $req,
'page' => $page,
'posts' => $posts,
+ 'archive' => $tarchive,
'bodyclass' => 'inarchive',
'breadcrumb' => '' . config('breadcrumb.home') . ' » Archive for: ' . $timestamp,
'pagination' => has_pagination($total, $perpage, $page),
@@ -1643,16 +1651,20 @@ get('/search/:keyword', function ($keyword) {
$perpage = config('search.perpage');
$posts = get_keyword($keyword, $page, $perpage);
+
+ $tsearch = new stdClass;
+ $tsearch->title = $keyword;
if (!$posts || $page < 1) {
// a non-existing page or no search result
render('404-search', array(
'title' => 'Search results not found! - ' . blog_title(),
'description' => 'Search results not found!',
+ 'search' => $tsearch,
'breadcrumb' => '' . config('breadcrumb.home') . ' » No search results',
'canonical' => site_url(),
'bodyclass' => 'error-404-search',
- 'is_search' => true,
+ 'is_404search' => true,
));
die;
}
@@ -1665,6 +1677,7 @@ get('/search/:keyword', function ($keyword) {
'canonical' => site_url() . 'search/' . strtolower($keyword),
'page' => $page,
'posts' => $posts,
+ 'search' => $tsearch,
'bodyclass' => 'insearch',
'breadcrumb' => '' . config('breadcrumb.home') . ' » Search results for: ' . tag_i18n($keyword),
'pagination' => has_pagination($total, $perpage, $page),
diff --git a/system/includes/functions.php b/system/includes/functions.php
index 24565e3..7b5879a 100644
--- a/system/includes/functions.php
+++ b/system/includes/functions.php
@@ -1346,9 +1346,12 @@ function has_pagination($total, $perpage, $page = 1)
if (!$total) {
$total = count(get_post_unsorted());
}
+ $totalPage = ceil($total / $perpage);
+ $number = 'Page '. $page . ' of ' . $totalPage;
return array(
'prev' => $page > 1,
- 'next' => $total > $page * $perpage
+ 'next' => $total > $page * $perpage,
+ 'number' => $number
);
}
diff --git a/system/plugins/urlify/.gitignore b/system/plugins/urlify/.gitignore
new file mode 100644
index 0000000..9df9b99
--- /dev/null
+++ b/system/plugins/urlify/.gitignore
@@ -0,0 +1,3 @@
+vendor
+composer.phar
+composer.lock
diff --git a/system/plugins/urlify/.travis.yml b/system/plugins/urlify/.travis.yml
new file mode 100644
index 0000000..e06af44
--- /dev/null
+++ b/system/plugins/urlify/.travis.yml
@@ -0,0 +1,15 @@
+language: php
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - hhvm
+
+before_script:
+ - composer install --no-interaction --prefer-source
+
+script:
+ - phpunit --coverage-text --verbose
diff --git a/system/plugins/urlify/INSTALL b/system/plugins/urlify/INSTALL
new file mode 100644
index 0000000..e92e55e
--- /dev/null
+++ b/system/plugins/urlify/INSTALL
@@ -0,0 +1,10 @@
+To install URLify, you can add it as a dependency ar by downloading the composer.phar executable.
+
+$ curl -s http://getcomposer.org/installer | php
+
+and run install
+
+$ php composer.phar install
+
+For more details, see http://getcomposer.org.
+
diff --git a/system/plugins/urlify/LICENSE b/system/plugins/urlify/LICENSE
new file mode 100644
index 0000000..5f4f225
--- /dev/null
+++ b/system/plugins/urlify/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) Django Software Foundation and individual contributors.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of Django nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/system/plugins/urlify/README.md b/system/plugins/urlify/README.md
new file mode 100644
index 0000000..334734d
--- /dev/null
+++ b/system/plugins/urlify/README.md
@@ -0,0 +1,94 @@
+# URLify for PHP
+
+A PHP port of [URLify.js](https://github.com/django/django/blob/master/django/contrib/admin/static/admin/js/urlify.js)
+from the Django project. Handles symbols from Latin languages as well as Arabic, Azerbaijani, Czech, German, Greek,
+Latvian, Lithuanian, Polish, Romanian, Bulgarian, Russian, Serbian, Turkish, Ukrainian and Vietnamese. Symbols it cannot
+transliterate it will simply omit.
+
+## Usage:
+
+To generate slugs for URLs:
+
+```php
+
+```
+
+To generate slugs for file names:
+
+```php
+
+```
+
+
+To simply transliterate characters:
+
+```php
+
+```
+
+To extend the character list:
+
+```php
+ '?', '®' => '(r)', '¼' => '1/4',
+ '½' => '1/2', '¾' => '3/4', '¶' => 'P'
+));
+
+echo URLify::downcode ('¿ ® ¼ ¼ ¾ ¶');
+// "? (r) 1/2 1/2 3/4 P"
+
+?>
+```
+
+To extend the list of words to remove:
+
+```php
+
+```
+
+To prioritize a certain language map:
+
+```php
+
+```
+Please note that the "ü" is transliterated to "ue" in the first case, whereas it results in a simple "u" in the latter.
diff --git a/system/plugins/urlify/URLify.php b/system/plugins/urlify/URLify.php
new file mode 100644
index 0000000..823f843
--- /dev/null
+++ b/system/plugins/urlify/URLify.php
@@ -0,0 +1,274 @@
+ array ( /* German */
+ 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss',
+ 'ẞ' => 'SS'
+ ),
+ 'latin' => array (
+ 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A','Ă' => 'A', 'Æ' => 'AE', 'Ç' =>
+ 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I',
+ 'Ï' => 'I', 'Ð' => 'D', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' =>
+ 'O', 'Ő' => 'O', 'Ø' => 'O','Ș' => 'S','Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ű' => 'U',
+ 'Ý' => 'Y', 'Þ' => 'TH', 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' =>
+ 'a', 'å' => 'a', 'ă' => 'a', 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e',
+ 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' =>
+ 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ő' => 'o', 'ø' => 'o', 'ș' => 's', 'ț' => 't', 'ù' => 'u', 'ú' => 'u',
+ 'û' => 'u', 'ü' => 'u', 'ű' => 'u', 'ý' => 'y', 'þ' => 'th', 'ÿ' => 'y'
+ ),
+ 'latin_symbols' => array (
+ '©' => '(c)'
+ ),
+ 'el' => array ( /* Greek */
+ 'α' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd', 'ε' => 'e', 'ζ' => 'z', 'η' => 'h', 'θ' => '8',
+ 'ι' => 'i', 'κ' => 'k', 'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => '3', 'ο' => 'o', 'π' => 'p',
+ 'ρ' => 'r', 'σ' => 's', 'τ' => 't', 'υ' => 'y', 'φ' => 'f', 'χ' => 'x', 'ψ' => 'ps', 'ω' => 'w',
+ 'ά' => 'a', 'έ' => 'e', 'ί' => 'i', 'ό' => 'o', 'ύ' => 'y', 'ή' => 'h', 'ώ' => 'w', 'ς' => 's',
+ 'ϊ' => 'i', 'ΰ' => 'y', 'ϋ' => 'y', 'ΐ' => 'i',
+ 'Α' => 'A', 'Β' => 'B', 'Γ' => 'G', 'Δ' => 'D', 'Ε' => 'E', 'Ζ' => 'Z', 'Η' => 'H', 'Θ' => '8',
+ 'Ι' => 'I', 'Κ' => 'K', 'Λ' => 'L', 'Μ' => 'M', 'Ν' => 'N', 'Ξ' => '3', 'Ο' => 'O', 'Π' => 'P',
+ 'Ρ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'Υ' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'PS', 'Ω' => 'W',
+ 'Ά' => 'A', 'Έ' => 'E', 'Ί' => 'I', 'Ό' => 'O', 'Ύ' => 'Y', 'Ή' => 'H', 'Ώ' => 'W', 'Ϊ' => 'I',
+ 'Ϋ' => 'Y'
+ ),
+ 'tr' => array ( /* Turkish */
+ 'ş' => 's', 'Ş' => 'S', 'ı' => 'i', 'İ' => 'I', 'ç' => 'c', 'Ç' => 'C', 'ü' => 'u', 'Ü' => 'U',
+ 'ö' => 'o', 'Ö' => 'O', 'ğ' => 'g', 'Ğ' => 'G'
+ ),
+ 'bg' => array( /* Bulgarian */
+ "Щ" => 'Sht', "Ш" => 'Sh', "Ч" => 'Ch', "Ц" => 'C', "Ю" => 'Yu', "Я" => 'Ya',
+ "Ж" => 'J', "А" => 'A', "Б" => 'B', "В" => 'V', "Г" => 'G', "Д" => 'D',
+ "Е" => 'E', "З" => 'Z', "И" => 'I', "Й" => 'Y', "К" => 'K', "Л" => 'L',
+ "М" => 'M', "Н" => 'N', "О" => 'O', "П" => 'P', "Р" => 'R', "С" => 'S',
+ "Т" => 'T', "У" => 'U', "Ф" => 'F', "Х" => 'H', "Ь" => '', "Ъ" => 'A',
+ "щ" => 'sht', "ш" => 'sh', "ч" => 'ch', "ц" => 'c', "ю" => 'yu', "я" => 'ya',
+ "ж" => 'j', "а" => 'a', "б" => 'b', "в" => 'v', "г" => 'g', "д" => 'd',
+ "е" => 'e', "з" => 'z', "и" => 'i', "й" => 'y', "к" => 'k', "л" => 'l',
+ "м" => 'm', "н" => 'n', "о" => 'o', "п" => 'p', "р" => 'r', "с" => 's',
+ "т" => 't', "у" => 'u', "ф" => 'f', "х" => 'h', "ь" => '', "ъ" => 'a'
+ ),
+ 'ru' => array ( /* Russian */
+ 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'ж' => 'zh',
+ 'з' => 'z', 'и' => 'i', 'й' => 'j', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o',
+ 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c',
+ 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sh', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu',
+ 'я' => 'ya',
+ 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo', 'Ж' => 'Zh',
+ 'З' => 'Z', 'И' => 'I', 'Й' => 'J', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O',
+ 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C',
+ 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sh', 'Ъ' => '', 'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'Yu',
+ 'Я' => 'Ya',
+ '№' => ''
+ ),
+ 'uk' => array ( /* Ukrainian */
+ 'Є' => 'Ye', 'І' => 'I', 'Ї' => 'Yi', 'Ґ' => 'G', 'є' => 'ye', 'і' => 'i', 'ї' => 'yi', 'ґ' => 'g'
+ ),
+ 'cs' => array ( /* Czech */
+ 'č' => 'c', 'ď' => 'd', 'ě' => 'e', 'ň' => 'n', 'ř' => 'r', 'š' => 's', 'ť' => 't', 'ů' => 'u',
+ 'ž' => 'z', 'Č' => 'C', 'Ď' => 'D', 'Ě' => 'E', 'Ň' => 'N', 'Ř' => 'R', 'Š' => 'S', 'Ť' => 'T',
+ 'Ů' => 'U', 'Ž' => 'Z'
+ ),
+ 'pl' => array ( /* Polish */
+ 'ą' => 'a', 'ć' => 'c', 'ę' => 'e', 'ł' => 'l', 'ń' => 'n', 'ó' => 'o', 'ś' => 's', 'ź' => 'z',
+ 'ż' => 'z', 'Ą' => 'A', 'Ć' => 'C', 'Ę' => 'e', 'Ł' => 'L', 'Ń' => 'N', 'Ó' => 'O', 'Ś' => 'S',
+ 'Ź' => 'Z', 'Ż' => 'Z'
+ ),
+ 'ro' => array ( /* Romanian */
+ 'ă' => 'a', 'â' => 'a', 'î' => 'i', 'ș' => 's', 'ț' => 't', 'Ţ' => 'T', 'ţ' => 't'
+ ),
+ 'lv' => array ( /* Latvian */
+ 'ā' => 'a', 'č' => 'c', 'ē' => 'e', 'ģ' => 'g', 'ī' => 'i', 'ķ' => 'k', 'ļ' => 'l', 'ņ' => 'n',
+ 'š' => 's', 'ū' => 'u', 'ž' => 'z', 'Ā' => 'A', 'Č' => 'C', 'Ē' => 'E', 'Ģ' => 'G', 'Ī' => 'i',
+ 'Ķ' => 'k', 'Ļ' => 'L', 'Ņ' => 'N', 'Š' => 'S', 'Ū' => 'u', 'Ž' => 'Z'
+ ),
+ 'lt' => array ( /* Lithuanian */
+ 'ą' => 'a', 'č' => 'c', 'ę' => 'e', 'ė' => 'e', 'į' => 'i', 'š' => 's', 'ų' => 'u', 'ū' => 'u', 'ž' => 'z',
+ 'Ą' => 'A', 'Č' => 'C', 'Ę' => 'E', 'Ė' => 'E', 'Į' => 'I', 'Š' => 'S', 'Ų' => 'U', 'Ū' => 'U', 'Ž' => 'Z'
+ ),
+ 'vn' => array ( /* Vietnamese */
+ 'Á' => 'A', 'À' => 'A', 'Ả' => 'A', 'Ã' => 'A', 'Ạ' => 'A', 'Ă' => 'A', 'Ắ' => 'A', 'Ằ' => 'A', 'Ẳ' => 'A', 'Ẵ' => 'A', 'Ặ' => 'A', 'Â' => 'A', 'Ấ' => 'A', 'Ầ' => 'A', 'Ẩ' => 'A', 'Ẫ' => 'A', 'Ậ' => 'A',
+ 'á' => 'a', 'à' => 'a', 'ả' => 'a', 'ã' => 'a', 'ạ' => 'a', 'ă' => 'a', 'ắ' => 'a', 'ằ' => 'a', 'ẳ' => 'a', 'ẵ' => 'a', 'ặ' => 'a', 'â' => 'a', 'ấ' => 'a', 'ầ' => 'a', 'ẩ' => 'a', 'ẫ' => 'a', 'ậ' => 'a',
+ 'É' => 'E', 'È' => 'E', 'Ẻ' => 'E', 'Ẽ' => 'E', 'Ẹ' => 'E', 'Ê' => 'E', 'Ế' => 'E', 'Ề' => 'E', 'Ể' => 'E', 'Ễ' => 'E', 'Ệ' => 'E',
+ 'é' => 'e', 'è' => 'e', 'ẻ' => 'e', 'ẽ' => 'e', 'ẹ' => 'e', 'ê' => 'e', 'ế' => 'e', 'ề' => 'e', 'ể' => 'e', 'ễ' => 'e', 'ệ' => 'e',
+ 'Í' => 'I', 'Ì' => 'I', 'Ỉ' => 'I', 'Ĩ' => 'I', 'Ị' => 'I', 'í' => 'i', 'ì' => 'i', 'ỉ' => 'i', 'ĩ' => 'i', 'ị' => 'i',
+ 'Ó' => 'O', 'Ò' => 'O', 'Ỏ' => 'O', 'Õ' => 'O', 'Ọ' => 'O', 'Ô' => 'O', 'Ố' => 'O', 'Ồ' => 'O', 'Ổ' => 'O', 'Ỗ' => 'O', 'Ộ' => 'O', 'Ơ' => 'O', 'Ớ' => 'O', 'Ờ' => 'O', 'Ở' => 'O', 'Ỡ' => 'O', 'Ợ' => 'O',
+ 'ó' => 'o', 'ò' => 'o', 'ỏ' => 'o', 'õ' => 'o', 'ọ' => 'o', 'ô' => 'o', 'ố' => 'o', 'ồ' => 'o', 'ổ' => 'o', 'ỗ' => 'o', 'ộ' => 'o', 'ơ' => 'o', 'ớ' => 'o', 'ờ' => 'o', 'ở' => 'o', 'ỡ' => 'o', 'ợ' => 'o',
+ 'Ú' => 'U', 'Ù' => 'U', 'Ủ' => 'U', 'Ũ' => 'U', 'Ụ' => 'U', 'Ư' => 'U', 'Ứ' => 'U', 'Ừ' => 'U', 'Ử' => 'U', 'Ữ' => 'U', 'Ự' => 'U',
+ 'ú' => 'u', 'ù' => 'u', 'ủ' => 'u', 'ũ' => 'u', 'ụ' => 'u', 'ư' => 'u', 'ứ' => 'u', 'ừ' => 'u', 'ử' => 'u', 'ữ' => 'u', 'ự' => 'u',
+ 'Ý' => 'Y', 'Ỳ' => 'Y', 'Ỷ' => 'Y', 'Ỹ' => 'Y', 'Ỵ' => 'Y', 'ý' => 'y', 'ỳ' => 'y', 'ỷ' => 'y', 'ỹ' => 'y', 'ỵ' => 'y',
+ 'Đ' => 'D', 'đ' => 'd'
+ ),
+ 'ar' => array ( /* Arabic */
+ 'أ' => 'a', 'ب' => 'b', 'ت' => 't', 'ث' => 'th', 'ج' => 'g', 'ح' => 'h', 'خ' => 'kh', 'د' => 'd',
+ 'ذ' => 'th', 'ر' => 'r', 'ز' => 'z', 'س' => 's', 'ش' => 'sh', 'ص' => 's', 'ض' => 'd', 'ط' => 't',
+ 'ظ' => 'th', 'ع' => 'aa', 'غ' => 'gh', 'ف' => 'f', 'ق' => 'k', 'ك' => 'k', 'ل' => 'l', 'م' => 'm',
+ 'ن' => 'n', 'ه' => 'h', 'و' => 'o', 'ي' => 'y'
+ ),
+ 'sr' => array ( /* Serbian */
+ 'ђ' => 'dj', 'ј' => 'j', 'љ' => 'lj', 'њ' => 'nj', 'ћ' => 'c', 'џ' => 'dz', 'đ' => 'dj',
+ 'Ђ' => 'Dj', 'Ј' => 'j', 'Љ' => 'Lj', 'Њ' => 'Nj', 'Ћ' => 'C', 'Џ' => 'Dz', 'Đ' => 'Dj'
+ ),
+ 'az' => array ( /* Azerbaijani */
+ 'ç' => 'c', 'ə' => 'e', 'ğ' => 'g', 'ı' => 'i', 'ö' => 'o', 'ş' => 's', 'ü' => 'u',
+ 'Ç' => 'C', 'Ə' => 'E', 'Ğ' => 'G', 'İ' => 'I', 'Ö' => 'O', 'Ş' => 'S', 'Ü' => 'U'
+ ),
+ 'slo' => array ( /* Slovakian */
+ 'DZ' => 'DZ', 'dz' => 'dz', 'DŽ' => 'DZ', 'dž' => 'dz', 'CH' => 'CH', 'Ĺ' => 'L', 'ĺ' => 'l', 'Ľ' => 'L',
+ 'ľ' => 'l', 'Ŕ' => 'R', 'ŕ' => 'r'
+ ),
+ 'add' => array ( /* Custom */
+ 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Ď' => 'D', 'ď' => 'd', 'Ĕ' => 'E', 'ĕ' => 'e', 'Ĝ' => 'G', 'ĝ' => 'g',
+ 'Ġ' => 'G', 'ġ' => 'g', 'Ĥ' => 'H', 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h', 'Ĭ' => 'I', 'ĭ' => 'i', 'IJ' => 'J', 'ij' => 'j',
+ 'Ĵ' => 'J', 'ĵ' => 'j', 'Ŀ' => 'L', 'ŀ' => 'l', 'ʼn' => 'n', 'Ō' => 'O', 'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Œ' => 'OE',
+ 'œ' => 'oe', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ŝ' => 'S', 'ŝ' => 's', 'Ŧ' => 'T', 'ŧ' => 't', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ŵ' => 'W',
+ 'ŵ' => 'w', 'Ŷ' => 'Y', 'ŷ' => 'y', 'Ÿ' => 'Y', 'ſ' => 'S', 'Ƒ' => 'F', 'ƒ' => 'f', 'Ǎ' => 'A', 'ǎ' => 'a', 'Ǐ' => 'I',
+ 'ǐ' => 'i', 'Ǒ' => 'O', 'ǒ' => 'o', 'Ǔ' => 'U', 'ǔ' => 'u', 'Ǖ' => 'U', 'ǖ' => 'u', 'Ǘ' => 'U', 'ǘ' => 'u', 'Ǚ' => 'U',
+ 'ǚ' => 'u', 'Ǜ' => 'U', 'ǜ' => 'u', 'Ǻ' => 'A', 'ǻ' => 'a', 'Ǽ' => 'AE', 'ǽ' => 'ae', 'Ǿ' => 'O', 'ǿ' => 'o'
+ )
+ );
+
+ /**
+ * List of words to remove from URLs.
+ */
+ public static $remove_list = array (
+ 'a', 'an', 'as', 'at', 'before', 'but', 'by', 'for', 'from',
+ 'is', 'in', 'into', 'like', 'of', 'off', 'on', 'onto', 'per',
+ 'since', 'than', 'the', 'this', 'that', 'to', 'up', 'via',
+ 'with'
+ );
+
+ /**
+ * The character map.
+ */
+ private static $map = array ();
+
+ /**
+ * The character list as a string.
+ */
+ private static $chars = '';
+
+ /**
+ * The character list as a regular expression.
+ */
+ private static $regex = '';
+
+ /**
+ * The current language
+ */
+ private static $language = '';
+
+ /**
+ * Initializes the character map.
+ */
+ private static function init ($language = "") {
+ if (count (self::$map) > 0 && (($language == "") || ($language == self::$language))) {
+ return;
+ }
+
+ /* Is a specific map associated with $language ? */
+ if (isset(self::$maps[$language]) && is_array(self::$maps[$language])) {
+ /* Move this map to end. This means it will have priority over others */
+ $m = self::$maps[$language];
+ unset(self::$maps[$language]);
+ self::$maps[$language] = $m;
+ }
+ /* Reset static vars */
+ self::$language = $language;
+ self::$map = array();
+ self::$chars = '';
+
+ foreach (self::$maps as $map) {
+ foreach ($map as $orig => $conv) {
+ self::$map[$orig] = $conv;
+ self::$chars .= $orig;
+ }
+ }
+
+ self::$regex = '/[' . self::$chars . ']/u';
+ }
+
+ /**
+ * Add new characters to the list. `$map` should be a hash.
+ */
+ public static function add_chars ($map) {
+ if (! is_array ($map)) {
+ throw new LogicException ('$map must be an associative array.');
+ }
+ self::$maps[] = $map;
+ self::$map = array ();
+ self::$chars = '';
+ }
+
+ /**
+ * Append words to the remove list. Accepts either single words
+ * or an array of words.
+ */
+ public static function remove_words ($words) {
+ $words = is_array ($words) ? $words : array ($words);
+ self::$remove_list = array_merge (self::$remove_list, $words);
+ }
+
+ /**
+ * Transliterates characters to their ASCII equivalents.
+ * $language specifies a priority for a specific language.
+ * The latter is useful if languages have different rules for the same character.
+ */
+ public static function downcode ($text, $language = "") {
+ self::init ($language);
+
+ if (preg_match_all (self::$regex, $text, $matches)) {
+ for ($i = 0; $i < count ($matches[0]); $i++) {
+ $char = $matches[0][$i];
+ if (isset (self::$map[$char])) {
+ $text = str_replace ($char, self::$map[$char], $text);
+ }
+ }
+ }
+ return $text;
+ }
+
+ /**
+ * Filters a string, e.g., "Petty theft" to "petty-theft"
+ */
+ public static function filter ($text, $length = 60, $language = "", $file_name = false, $use_remove_list = true) {
+ $text = self::downcode ($text,$language);
+
+ if ($use_remove_list) {
+ // remove all these words from the string before urlifying
+ $text = preg_replace ('/\b(' . join ('|', self::$remove_list) . ')\b/i', '', $text);
+ }
+
+ // if downcode doesn't hit, the char will be stripped here
+ $remove_pattern = ($file_name) ? '/[^_\-.\-a-zA-Z0-9\s]/u' : '/[^\s_\-a-zA-Z0-9]/u';
+ $text = preg_replace ($remove_pattern, '', $text); // remove unneeded chars
+ $text = str_replace ('_', ' ', $text); // treat underscores as spaces
+ $text = preg_replace ('/^\s+|\s+$/u', '', $text); // trim leading/trailing spaces
+ $text = preg_replace ('/[-\s]+/u', '-', $text); // convert spaces to hyphens
+ $text = strtolower ($text); // convert to lowercase
+ return trim (substr ($text, 0, $length), '-'); // trim to first $length chars
+ }
+
+ /**
+ * Alias of `URLify::downcode()`.
+ */
+ public static function transliterate ($text) {
+ return self::downcode ($text);
+ }
+}
diff --git a/system/plugins/urlify/composer.json b/system/plugins/urlify/composer.json
new file mode 100644
index 0000000..b226f8e
--- /dev/null
+++ b/system/plugins/urlify/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "jbroadway/urlify",
+ "type": "library",
+ "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.",
+ "keywords": ["urlify","transliterate","translit","transliteration","url","encode","slug","link","iconv"],
+ "homepage": "https://github.com/jbroadway/urlify",
+ "license": "BSD",
+ "authors": [
+ {
+ "name": "Johnny Broadway",
+ "email": "johnny@johnnybroadway.com",
+ "homepage": "http://www.johnnybroadway.com/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-0": { "URLify": "" }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
diff --git a/system/plugins/urlify/phpunit.xml b/system/plugins/urlify/phpunit.xml
new file mode 100644
index 0000000..eeebfcc
--- /dev/null
+++ b/system/plugins/urlify/phpunit.xml
@@ -0,0 +1,8 @@
+
+
+ tests
+
+
+
+
+
diff --git a/system/plugins/urlify/scripts/downcode.php b/system/plugins/urlify/scripts/downcode.php
new file mode 100644
index 0000000..f2a7fda
--- /dev/null
+++ b/system/plugins/urlify/scripts/downcode.php
@@ -0,0 +1,20 @@
+ 2) {
+ die ("Usage (argument): php " . basename(__FILE__) . " \"\"\nUsage (pipe): | php " . basename(__FILE__) . "\n");
+}
+
+//Process the provided argument
+if($argc === 2) {
+ $s = $argv[1];
+//Or read from stdin if the argument wasn't present
+} else {
+ $piped = true;
+ $s = file_get_contents("php://stdin");
+}
+
+echo URLify::downcode ($s) . ($piped ? "\n" : "");
diff --git a/system/plugins/urlify/scripts/filter.php b/system/plugins/urlify/scripts/filter.php
new file mode 100644
index 0000000..aec6a0a
--- /dev/null
+++ b/system/plugins/urlify/scripts/filter.php
@@ -0,0 +1,20 @@
+ 2) {
+ die ("Usage (argument): php " . basename(__FILE__) . " \"\"\nUsage (pipe): | php " . basename(__FILE__) . "\n");
+}
+
+//Process the provided argument
+if($argc === 2) {
+ $s = $argv[1];
+//Or read from stdin if the argument wasn't present
+} else {
+ $piped = true;
+ $s = file_get_contents("php://stdin");
+}
+
+echo URLify::filter ($s) . ($piped ? "\n" : "");
diff --git a/system/plugins/urlify/scripts/transliterate.php b/system/plugins/urlify/scripts/transliterate.php
new file mode 100644
index 0000000..258581b
--- /dev/null
+++ b/system/plugins/urlify/scripts/transliterate.php
@@ -0,0 +1,20 @@
+ 2) {
+ die ("Usage (argument): php " . basename(__FILE__) . " \"\"\nUsage (pipe): | php " . basename(__FILE__) . "\n");
+}
+
+//Process the provided argument
+if($argc === 2) {
+ $s = $argv[1];
+//Or read from stdin if the argument wasn't present
+} else {
+ $piped = true;
+ $s = file_get_contents("php://stdin");
+}
+
+echo URLify::transliterate($s) . ($piped ? "\n" : "");
diff --git a/system/plugins/urlify/tests/URLifyTest.php b/system/plugins/urlify/tests/URLifyTest.php
new file mode 100644
index 0000000..5e09401
--- /dev/null
+++ b/system/plugins/urlify/tests/URLifyTest.php
@@ -0,0 +1,54 @@
+assertEquals (' J\'etudie le francais ', URLify::downcode (' J\'étudie le français '));
+ $this->assertEquals ('Lo siento, no hablo espanol.', URLify::downcode ('Lo siento, no hablo español.'));
+ $this->assertEquals ('F3PWS', URLify::downcode ('ΦΞΠΏΣ'));
+ $this->assertEquals ('foo-bar', URLify::filter ('_foo_bar_'));
+ }
+
+ function test_filter () {
+ $this->assertEquals ('jetudie-le-francais', URLify::filter (' J\'étudie le français '));
+ $this->assertEquals ('lo-siento-no-hablo-espanol', URLify::filter ('Lo siento, no hablo español.'));
+ $this->assertEquals ('f3pws', URLify::filter ('ΦΞΠΏΣ'));
+ $this->assertEquals ('', URLify::filter('大般若經'));
+ $this->assertEquals ('test-.txt', URLify::filter('test-大般若經.txt', 60, "", $file_name = true));
+ $this->assertEquals ('ykrhy-ltoytr', URLify::filter('ياكرهي لتويتر'));
+ $this->assertEquals ('foto.jpg', URLify::filter ('фото.jpg', 60, "", $file_name = true));
+ // priorization of language-specific maps
+ $this->assertEquals ('aouaou', URLify::filter ('ÄÖÜäöü',60,"tr"));
+ $this->assertEquals ('aeoeueaeoeue', URLify::filter ('ÄÖÜäöü',60,"de"));
+
+ $this->assertEquals ('bobby-mcferrin-dont-worry-be-happy', URLify::filter ("Bobby McFerrin — Don't worry be happy",600,"en"));
+ // test stripping and conversion of UTF-8 spaces
+ $this->assertEquals ('test-mahito-mukai', URLify::filter('向井 真人test (Mahito Mukai)'));
+ }
+
+ function test_add_chars () {
+ $this->assertEquals ('¿ ® ¼ ¼ ¾ ¶', URLify::downcode ('¿ ® ¼ ¼ ¾ ¶'));
+ URLify::add_chars (array (
+ '¿' => '?', '®' => '(r)', '¼' => '1/4',
+ '¼' => '1/2', '¾' => '3/4', '¶' => 'P'
+ ));
+ $this->assertEquals ('? (r) 1/2 1/2 3/4 P', URLify::downcode ('¿ ® ¼ ¼ ¾ ¶'));
+ }
+
+ function test_remove_words () {
+ $this->assertEquals ('foo-bar', URLify::filter ('foo bar'));
+ URLify::remove_words (array ('foo', 'bar'));
+ $this->assertEquals ('', URLify::filter ('foo bar'));
+ }
+
+ function test_many_rounds_with_unknown_language_code () {
+ for ($i = 0; $i < 1000; $i++) {
+ URLify::downcode ('Lo siento, no hablo español.',-1);
+ }
+ }
+
+ function test_remove_words_disable () {
+ URLify::remove_words (array ('foo', 'bar'));
+ $this->assertEquals ('foo-bar', URLify::filter ('foo bar', 60, '', false, false));
+ }
+}
+
+?>
diff --git a/system/plugins/urlify/tests/bootstrap.php b/system/plugins/urlify/tests/bootstrap.php
new file mode 100644
index 0000000..d56d466
--- /dev/null
+++ b/system/plugins/urlify/tests/bootstrap.php
@@ -0,0 +1,9 @@
+getCurrentInfo();
diff --git a/system/vendor/composer/autoload_files.php b/system/vendor/composer/autoload_files.php
index a582309..1e0a472 100644
--- a/system/vendor/composer/autoload_files.php
+++ b/system/vendor/composer/autoload_files.php
@@ -6,10 +6,11 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname(dirname($vendorDir));
return array(
- $vendorDir . '/ircmaxell/password-compat/lib/password.php',
- $baseDir . '/system/includes/dispatch.php',
- $baseDir . '/system/includes/functions.php',
- $baseDir . '/system/admin/admin.php',
- $baseDir . '/system/includes/session.php',
- $baseDir . '/system/includes/opml.php',
+ '05669301f06448944ce5eb260126f84e' => $vendorDir . '/ircmaxell/password-compat/lib/password.php',
+ '7acf2c394ac19fdcadb351c1328f6361' => $baseDir . '/system/includes/dispatch.php',
+ '72aa34b3aa4866e1c401ecb30ee29a30' => $baseDir . '/system/includes/functions.php',
+ '22715f0e6ee6f21bb7ada1f56df82c76' => $baseDir . '/system/admin/admin.php',
+ '372406877c969643fd5d4bdc28f7a64a' => $baseDir . '/system/includes/session.php',
+ '46286444bb46675598ca39831bb66c52' => $baseDir . '/system/includes/opml.php',
+ 'e1070fa2f8e817d10783474c01748a52' => $baseDir . '/system/plugins/urlify/URLify.php',
);
diff --git a/system/vendor/composer/autoload_real.php b/system/vendor/composer/autoload_real.php
index 7593687..389be55 100644
--- a/system/vendor/composer/autoload_real.php
+++ b/system/vendor/composer/autoload_real.php
@@ -41,15 +41,19 @@ class ComposerAutoloaderInit202d771b98d07410d9e52c5a90cbc9e1
$loader->register(true);
$includeFiles = require __DIR__ . '/autoload_files.php';
- foreach ($includeFiles as $file) {
- composerRequire202d771b98d07410d9e52c5a90cbc9e1($file);
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequire202d771b98d07410d9e52c5a90cbc9e1($fileIdentifier, $file);
}
return $loader;
}
}
-function composerRequire202d771b98d07410d9e52c5a90cbc9e1($file)
+function composerRequire202d771b98d07410d9e52c5a90cbc9e1($fileIdentifier, $file)
{
- require $file;
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
}