aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/classes/ElggGroup.php2
-rw-r--r--engine/classes/ElggMemcache.php6
-rw-r--r--engine/classes/ElggPluginManifest.php48
-rw-r--r--engine/classes/ElggPluginManifestParser18.php11
-rw-r--r--engine/classes/ElggSite.php27
-rw-r--r--engine/classes/ElggTranslit.php262
-rw-r--r--engine/lib/actions.php59
-rw-r--r--engine/lib/admin.php3
-rw-r--r--engine/lib/cache.php1
-rw-r--r--engine/lib/configuration.php4
-rw-r--r--engine/lib/database.php4
-rw-r--r--engine/lib/elgglib.php49
-rw-r--r--engine/lib/entities.php23
-rw-r--r--engine/lib/extender.php5
-rw-r--r--engine/lib/filestore.php6
-rw-r--r--engine/lib/input.php6
-rw-r--r--engine/lib/languages.php164
-rw-r--r--engine/lib/metadata.php13
-rw-r--r--engine/lib/navigation.php15
-rw-r--r--engine/lib/notification.php16
-rw-r--r--engine/lib/output.php18
-rw-r--r--engine/lib/pagehandler.php14
-rw-r--r--engine/lib/plugins.php4
-rw-r--r--engine/lib/relationships.php9
-rw-r--r--engine/lib/river.php12
-rw-r--r--engine/lib/sessions.php11
-rw-r--r--engine/lib/statistics.php4
-rw-r--r--engine/lib/system_log.php13
-rw-r--r--engine/lib/users.php9
-rw-r--r--engine/lib/views.php8
-rw-r--r--engine/start.php12
-rw-r--r--engine/tests/api/metadata.php21
-rw-r--r--engine/tests/api/plugins.php18
-rw-r--r--engine/tests/regression/trac_bugs.php27
-rw-r--r--engine/tests/test_files/plugin_18/manifest.xml3
35 files changed, 679 insertions, 228 deletions
diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php
index f7f67bf41..121186196 100644
--- a/engine/classes/ElggGroup.php
+++ b/engine/classes/ElggGroup.php
@@ -16,8 +16,6 @@ class ElggGroup extends ElggEntity
* Sets the type to group.
*
* @return void
- *
- * @deprecated 1.8 Use initializeAttributes
*/
protected function initializeAttributes() {
parent::initializeAttributes();
diff --git a/engine/classes/ElggMemcache.php b/engine/classes/ElggMemcache.php
index f27b017d0..d9539b9cb 100644
--- a/engine/classes/ElggMemcache.php
+++ b/engine/classes/ElggMemcache.php
@@ -40,7 +40,7 @@ class ElggMemcache extends ElggSharedMemoryCache {
// Do we have memcache?
if (!class_exists('Memcache')) {
- throw new ConfigurationException(elgg_echo('memcache:notinstalled'));
+ throw new ConfigurationException('PHP memcache module not installed, you must install php5-memcache');
}
// Create memcache object
@@ -48,7 +48,7 @@ class ElggMemcache extends ElggSharedMemoryCache {
// Now add servers
if (!$CONFIG->memcache_servers) {
- throw new ConfigurationException(elgg_echo('memcache:noservers'));
+ throw new ConfigurationException('No memcache servers defined, please populate the $CONFIG->memcache_servers variable');
}
if (is_callable(array($this->memcache, 'addServer'))) {
@@ -85,7 +85,7 @@ class ElggMemcache extends ElggSharedMemoryCache {
// Get version
$this->version = $this->memcache->getVersion();
if (version_compare($this->version, ElggMemcache::$MINSERVERVERSION, '<')) {
- $msg = elgg_echo('memcache:versiontoolow',
+ $msg = vsprintf('Memcache needs at least version %s to run, you are running %s',
array(ElggMemcache::$MINSERVERVERSION,
$this->version
));
diff --git a/engine/classes/ElggPluginManifest.php b/engine/classes/ElggPluginManifest.php
index 7aa702d47..a4f5bb95d 100644
--- a/engine/classes/ElggPluginManifest.php
+++ b/engine/classes/ElggPluginManifest.php
@@ -264,7 +264,7 @@ class ElggPluginManifest {
/**
* Returns the license
*
- * @return sting
+ * @return string
*/
public function getLicense() {
// license vs licence. Use license.
@@ -276,6 +276,32 @@ class ElggPluginManifest {
}
}
+ /**
+ * Returns the repository url
+ *
+ * @return string
+ */
+ public function getRepositoryURL() {
+ return $this->parser->getAttribute('repository');
+ }
+
+ /**
+ * Returns the bug tracker page
+ *
+ * @return string
+ */
+ public function getBugTrackerURL() {
+ return $this->parser->getAttribute('bugtracker');
+ }
+
+ /**
+ * Returns the donations page
+ *
+ * @return string
+ */
+ public function getDonationsPageURL() {
+ return $this->parser->getAttribute('donations');
+ }
/**
* Returns the version of the plugin.
@@ -319,12 +345,26 @@ class ElggPluginManifest {
* @return array
*/
public function getCategories() {
+ $bundled_plugins = array('blog', 'bookmarks', 'categories',
+ 'custom_index', 'dashboard', 'developers', 'diagnostics',
+ 'embed', 'externalpages', 'file', 'garbagecollector',
+ 'groups', 'htmlawed', 'invitefriends', 'likes',
+ 'logbrowser', 'logrotate', 'members', 'messageboard',
+ 'messages', 'notifications', 'oauth_api', 'pages', 'profile',
+ 'reportedcontent', 'search', 'tagcloud', 'thewire', 'tinymce',
+ 'twitter', 'twitter_api', 'uservalidationbyemail', 'zaudio',
+ );
+
$cats = $this->parser->getAttribute('category');
if (!$cats) {
$cats = array();
}
+ if (in_array('bundled', $cats) && !in_array($this->getPluginID(), $bundled_plugins)) {
+ unset($cats[array_search('bundled', $cats)]);
+ }
+
return $cats;
}
@@ -442,7 +482,7 @@ class ElggPluginManifest {
* Normalizes a dependency array using the defined structs.
* Can be used with either requires or suggests.
*
- * @param array $dep An dependency array.
+ * @param array $dep A dependency array.
* @return array The normalized deps array.
*/
private function normalizeDep($dep) {
@@ -486,8 +526,10 @@ class ElggPluginManifest {
break;
}
}
-
break;
+ default:
+ // unrecognized so we just return the raw dependency
+ return $dep;
}
$normalized_dep = $this->buildStruct($struct, $dep);
diff --git a/engine/classes/ElggPluginManifestParser18.php b/engine/classes/ElggPluginManifestParser18.php
index 554e28c02..3b753f17b 100644
--- a/engine/classes/ElggPluginManifestParser18.php
+++ b/engine/classes/ElggPluginManifestParser18.php
@@ -13,10 +13,10 @@ class ElggPluginManifestParser18 extends ElggPluginManifestParser {
* @var array
*/
protected $validAttributes = array(
- 'name', 'author', 'version', 'blurb', 'description',
- 'website', 'copyright', 'license', 'requires', 'suggests',
- 'screenshot', 'category', 'conflicts', 'provides',
- 'activate_on_install'
+ 'name', 'author', 'version', 'blurb', 'description','website',
+ 'repository', 'bugtracker', 'donations', 'copyright', 'license',
+ 'requires', 'suggests', 'conflicts', 'provides',
+ 'screenshot', 'category', 'activate_on_install'
);
/**
@@ -46,6 +46,9 @@ class ElggPluginManifestParser18 extends ElggPluginManifestParser {
case 'website':
case 'copyright':
case 'license':
+ case 'repository':
+ case 'bugtracker':
+ case 'donations':
case 'activate_on_install':
$parsed[$element->name] = $element->content;
break;
diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php
index 6d07778a9..401939005 100644
--- a/engine/classes/ElggSite.php
+++ b/engine/classes/ElggSite.php
@@ -381,14 +381,24 @@ class ElggSite extends ElggEntity {
public function checkWalledGarden() {
global $CONFIG;
- if ($CONFIG->walled_garden && !elgg_is_logged_in()) {
- // hook into the index system call at the highest priority
- elgg_register_plugin_hook_handler('index', 'system', 'elgg_walled_garden_index', 1);
-
- if (!$this->isPublicPage()) {
- $_SESSION['last_forward_from'] = current_page_url();
- register_error(elgg_echo('loggedinrequired'));
- forward();
+ if ($CONFIG->walled_garden) {
+ if ($CONFIG->default_access == ACCESS_PUBLIC) {
+ $CONFIG->default_access = ACCESS_LOGGED_IN;
+ }
+ elgg_register_plugin_hook_handler(
+ 'access:collections:write',
+ 'user',
+ '_elgg_walled_garden_remove_public_access');
+
+ if (!elgg_is_logged_in()) {
+ // hook into the index system call at the highest priority
+ elgg_register_plugin_hook_handler('index', 'system', 'elgg_walled_garden_index', 1);
+
+ if (!$this->isPublicPage()) {
+ $_SESSION['last_forward_from'] = current_page_url();
+ register_error(elgg_echo('loggedinrequired'));
+ forward();
+ }
}
}
}
@@ -423,6 +433,7 @@ class ElggSite extends ElggEntity {
// default public pages
$defaults = array(
'walled_garden/.*',
+ 'login',
'action/login',
'register',
'action/register',
diff --git a/engine/classes/ElggTranslit.php b/engine/classes/ElggTranslit.php
new file mode 100644
index 000000000..676c59fc8
--- /dev/null
+++ b/engine/classes/ElggTranslit.php
@@ -0,0 +1,262 @@
+<?php
+/**
+ * Elgg Transliterate
+ *
+ * For creating "friendly titles" for URLs
+ *
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ *
+ * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ *
+ * @author Steve Clay <steve@mrclay.org>
+ * @package Elgg.Core
+ *
+ * @access private Plugin authors should not use this directly
+ */
+class ElggTranslit {
+
+ /**
+ * Create a version of a string for embedding in a URL
+ * @param string $string a UTF-8 string
+ * @param string $separator
+ * @return string
+ */
+ static public function urlize($string, $separator = '-') {
+ // Iñtërnâtiônàlizætiøn, AND 日本語!
+
+ // try to force combined chars because the translit map and others expect it
+ if (self::hasNormalizerSupport()) {
+ $nfc = normalizer_normalize($string);
+ if (is_string($nfc)) {
+ $string = $nfc;
+ }
+ }
+ // Internationalization, AND 日本語!
+ $string = self::transliterateAscii($string);
+
+ // more translation
+ $string = strtr($string, array(
+ // Euro/GBP
+ "\xE2\x82\xAC" /* € */ => 'E', "\xC2\xA3" /* £ */ => 'GBP',
+ ));
+
+ // remove all ASCII except 0-9a-zA-Z, hyphen, underscore, and whitespace
+ // note: "x" modifier did not work with this pattern.
+ $string = preg_replace('~['
+ . '\x00-\x08' # control chars
+ . '\x0b\x0c' # vert tab, form feed
+ . '\x0e-\x1f' # control chars
+ . '\x21-\x2c' # ! ... ,
+ . '\x2e\x2f' # . slash
+ . '\x3a-\x40' # : ... @
+ . '\x5b-\x5e' # [ ... ^
+ . '\x60' # `
+ . '\x7b-\x7f' # { ... DEL
+ . ']~', '', $string);
+ $string = strtr($string, '', '');
+
+ // internationalization, and 日本語!
+ // note: not using elgg_strtolower to keep this class portable
+ $string = is_callable('mb_strtolower')
+ ? mb_strtolower($string, 'UTF-8')
+ : strtolower($string);
+
+ // split by ASCII chars not in 0-9a-zA-Z
+ // note: we cannot use [^0-9a-zA-Z] because that matches multibyte chars.
+ // note: "x" modifier did not work with this pattern.
+ $pattern = '~['
+ . '\x00-\x2f' # controls ... slash
+ . '\x3a-\x40' # : ... @
+ . '\x5b-\x60' # [ ... `
+ . '\x7b-\x7f' # { ... DEL
+ . ']+~x';
+
+ // ['internationalization', 'and', '日本語']
+ $words = preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY);
+
+ // ['internationalization', 'and', '%E6%97%A5%E6%9C%AC%E8%AA%9E']
+ $words = array_map('urlencode', $words);
+
+ // internationalization-and-%E6%97%A5%E6%9C%AC%E8%AA%9E
+ return implode($separator, $words);
+ }
+
+ /**
+ * Transliterate Western multibyte chars to ASCII
+ * @param string $utf8 a UTF-8 string
+ * @return string
+ */
+ static public function transliterateAscii($utf8) {
+ static $map = null;
+ if (!preg_match('/[\x80-\xff]/', $utf8)) {
+ return $utf8;
+ }
+ if (null === $map) {
+ $map = self::getAsciiTranslitMap();
+ }
+ return strtr($utf8, $map);
+ }
+
+ /**
+ * Get array of UTF-8 (NFC) character replacements.
+ *
+ * @return array
+ */
+ static public function getAsciiTranslitMap() {
+ return array(
+ // Decompositions for Latin-1 Supplement
+ "\xC2\xAA" /* ª */ => 'a', "\xC2\xBA" /* º */ => 'o', "\xC3\x80" /* À */ => 'A',
+ "\xC3\x81" /* Á */ => 'A', "\xC3\x82" /* Â */ => 'A', "\xC3\x83" /* Ã */ => 'A',
+ "\xC3\x84" /* Ä */ => 'A', "\xC3\x85" /* Å */ => 'A', "\xC3\x86" /* Æ */ => 'AE',
+ "\xC3\x87" /* Ç */ => 'C', "\xC3\x88" /* È */ => 'E', "\xC3\x89" /* É */ => 'E',
+ "\xC3\x8A" /* Ê */ => 'E', "\xC3\x8B" /* Ë */ => 'E', "\xC3\x8C" /* Ì */ => 'I',
+ "\xC3\x8D" /* Í */ => 'I', "\xC3\x8E" /* Î */ => 'I', "\xC3\x8F" /* Ï */ => 'I',
+ "\xC3\x90" /* Ð */ => 'D', "\xC3\x91" /* Ñ */ => 'N', "\xC3\x92" /* Ò */ => 'O',
+ "\xC3\x93" /* Ó */ => 'O', "\xC3\x94" /* Ô */ => 'O', "\xC3\x95" /* Õ */ => 'O',
+ "\xC3\x96" /* Ö */ => 'O', "\xC3\x99" /* Ù */ => 'U', "\xC3\x9A" /* Ú */ => 'U',
+ "\xC3\x9B" /* Û */ => 'U', "\xC3\x9C" /* Ü */ => 'U', "\xC3\x9D" /* Ý */ => 'Y',
+ "\xC3\x9E" /* Þ */ => 'TH', "\xC3\x9F" /* ß */ => 'ss', "\xC3\xA0" /* à */ => 'a',
+ "\xC3\xA1" /* á */ => 'a', "\xC3\xA2" /* â */ => 'a', "\xC3\xA3" /* ã */ => 'a',
+ "\xC3\xA4" /* ä */ => 'a', "\xC3\xA5" /* å */ => 'a', "\xC3\xA6" /* æ */ => 'ae',
+ "\xC3\xA7" /* ç */ => 'c', "\xC3\xA8" /* è */ => 'e', "\xC3\xA9" /* é */ => 'e',
+ "\xC3\xAA" /* ê */ => 'e', "\xC3\xAB" /* ë */ => 'e', "\xC3\xAC" /* ì */ => 'i',
+ "\xC3\xAD" /* í */ => 'i', "\xC3\xAE" /* î */ => 'i', "\xC3\xAF" /* ï */ => 'i',
+ "\xC3\xB0" /* ð */ => 'd', "\xC3\xB1" /* ñ */ => 'n', "\xC3\xB2" /* ò */ => 'o',
+ "\xC3\xB3" /* ó */ => 'o', "\xC3\xB4" /* ô */ => 'o', "\xC3\xB5" /* õ */ => 'o',
+ "\xC3\xB6" /* ö */ => 'o', "\xC3\xB8" /* ø */ => 'o', "\xC3\xB9" /* ù */ => 'u',
+ "\xC3\xBA" /* ú */ => 'u', "\xC3\xBB" /* û */ => 'u', "\xC3\xBC" /* ü */ => 'u',
+ "\xC3\xBD" /* ý */ => 'y', "\xC3\xBE" /* þ */ => 'th', "\xC3\xBF" /* ÿ */ => 'y',
+ "\xC3\x98" /* Ø */ => 'O',
+ // Decompositions for Latin Extended-A
+ "\xC4\x80" /* Ā */ => 'A', "\xC4\x81" /* ā */ => 'a', "\xC4\x82" /* Ă */ => 'A',
+ "\xC4\x83" /* ă */ => 'a', "\xC4\x84" /* Ą */ => 'A', "\xC4\x85" /* ą */ => 'a',
+ "\xC4\x86" /* Ć */ => 'C', "\xC4\x87" /* ć */ => 'c', "\xC4\x88" /* Ĉ */ => 'C',
+ "\xC4\x89" /* ĉ */ => 'c', "\xC4\x8A" /* Ċ */ => 'C', "\xC4\x8B" /* ċ */ => 'c',
+ "\xC4\x8C" /* Č */ => 'C', "\xC4\x8D" /* č */ => 'c', "\xC4\x8E" /* Ď */ => 'D',
+ "\xC4\x8F" /* ď */ => 'd', "\xC4\x90" /* Đ */ => 'D', "\xC4\x91" /* đ */ => 'd',
+ "\xC4\x92" /* Ē */ => 'E', "\xC4\x93" /* ē */ => 'e', "\xC4\x94" /* Ĕ */ => 'E',
+ "\xC4\x95" /* ĕ */ => 'e', "\xC4\x96" /* Ė */ => 'E', "\xC4\x97" /* ė */ => 'e',
+ "\xC4\x98" /* Ę */ => 'E', "\xC4\x99" /* ę */ => 'e', "\xC4\x9A" /* Ě */ => 'E',
+ "\xC4\x9B" /* ě */ => 'e', "\xC4\x9C" /* Ĝ */ => 'G', "\xC4\x9D" /* ĝ */ => 'g',
+ "\xC4\x9E" /* Ğ */ => 'G', "\xC4\x9F" /* ğ */ => 'g', "\xC4\xA0" /* Ġ */ => 'G',
+ "\xC4\xA1" /* ġ */ => 'g', "\xC4\xA2" /* Ģ */ => 'G', "\xC4\xA3" /* ģ */ => 'g',
+ "\xC4\xA4" /* Ĥ */ => 'H', "\xC4\xA5" /* ĥ */ => 'h', "\xC4\xA6" /* Ħ */ => 'H',
+ "\xC4\xA7" /* ħ */ => 'h', "\xC4\xA8" /* Ĩ */ => 'I', "\xC4\xA9" /* ĩ */ => 'i',
+ "\xC4\xAA" /* Ī */ => 'I', "\xC4\xAB" /* ī */ => 'i', "\xC4\xAC" /* Ĭ */ => 'I',
+ "\xC4\xAD" /* ĭ */ => 'i', "\xC4\xAE" /* Į */ => 'I', "\xC4\xAF" /* į */ => 'i',
+ "\xC4\xB0" /* İ */ => 'I', "\xC4\xB1" /* ı */ => 'i', "\xC4\xB2" /* IJ */ => 'IJ',
+ "\xC4\xB3" /* ij */ => 'ij', "\xC4\xB4" /* Ĵ */ => 'J', "\xC4\xB5" /* ĵ */ => 'j',
+ "\xC4\xB6" /* Ķ */ => 'K', "\xC4\xB7" /* ķ */ => 'k', "\xC4\xB8" /* ĸ */ => 'k',
+ "\xC4\xB9" /* Ĺ */ => 'L', "\xC4\xBA" /* ĺ */ => 'l', "\xC4\xBB" /* Ļ */ => 'L',
+ "\xC4\xBC" /* ļ */ => 'l', "\xC4\xBD" /* Ľ */ => 'L', "\xC4\xBE" /* ľ */ => 'l',
+ "\xC4\xBF" /* Ŀ */ => 'L', "\xC5\x80" /* ŀ */ => 'l', "\xC5\x81" /* Ł */ => 'L',
+ "\xC5\x82" /* ł */ => 'l', "\xC5\x83" /* Ń */ => 'N', "\xC5\x84" /* ń */ => 'n',
+ "\xC5\x85" /* Ņ */ => 'N', "\xC5\x86" /* ņ */ => 'n', "\xC5\x87" /* Ň */ => 'N',
+ "\xC5\x88" /* ň */ => 'n', "\xC5\x89" /* ʼn */ => 'N', "\xC5\x8A" /* Ŋ */ => 'n',
+ "\xC5\x8B" /* ŋ */ => 'N', "\xC5\x8C" /* Ō */ => 'O', "\xC5\x8D" /* ō */ => 'o',
+ "\xC5\x8E" /* Ŏ */ => 'O', "\xC5\x8F" /* ŏ */ => 'o', "\xC5\x90" /* Ő */ => 'O',
+ "\xC5\x91" /* ő */ => 'o', "\xC5\x92" /* Œ */ => 'OE', "\xC5\x93" /* œ */ => 'oe',
+ "\xC5\x94" /* Ŕ */ => 'R', "\xC5\x95" /* ŕ */ => 'r', "\xC5\x96" /* Ŗ */ => 'R',
+ "\xC5\x97" /* ŗ */ => 'r', "\xC5\x98" /* Ř */ => 'R', "\xC5\x99" /* ř */ => 'r',
+ "\xC5\x9A" /* Ś */ => 'S', "\xC5\x9B" /* ś */ => 's', "\xC5\x9C" /* Ŝ */ => 'S',
+ "\xC5\x9D" /* ŝ */ => 's', "\xC5\x9E" /* Ş */ => 'S', "\xC5\x9F" /* ş */ => 's',
+ "\xC5\xA0" /* Š */ => 'S', "\xC5\xA1" /* š */ => 's', "\xC5\xA2" /* Ţ */ => 'T',
+ "\xC5\xA3" /* ţ */ => 't', "\xC5\xA4" /* Ť */ => 'T', "\xC5\xA5" /* ť */ => 't',
+ "\xC5\xA6" /* Ŧ */ => 'T', "\xC5\xA7" /* ŧ */ => 't', "\xC5\xA8" /* Ũ */ => 'U',
+ "\xC5\xA9" /* ũ */ => 'u', "\xC5\xAA" /* Ū */ => 'U', "\xC5\xAB" /* ū */ => 'u',
+ "\xC5\xAC" /* Ŭ */ => 'U', "\xC5\xAD" /* ŭ */ => 'u', "\xC5\xAE" /* Ů */ => 'U',
+ "\xC5\xAF" /* ů */ => 'u', "\xC5\xB0" /* Ű */ => 'U', "\xC5\xB1" /* ű */ => 'u',
+ "\xC5\xB2" /* Ų */ => 'U', "\xC5\xB3" /* ų */ => 'u', "\xC5\xB4" /* Ŵ */ => 'W',
+ "\xC5\xB5" /* ŵ */ => 'w', "\xC5\xB6" /* Ŷ */ => 'Y', "\xC5\xB7" /* ŷ */ => 'y',
+ "\xC5\xB8" /* Ÿ */ => 'Y', "\xC5\xB9" /* Ź */ => 'Z', "\xC5\xBA" /* ź */ => 'z',
+ "\xC5\xBB" /* Ż */ => 'Z', "\xC5\xBC" /* ż */ => 'z', "\xC5\xBD" /* Ž */ => 'Z',
+ "\xC5\xBE" /* ž */ => 'z', "\xC5\xBF" /* ſ */ => 's',
+ // Decompositions for Latin Extended-B
+ "\xC8\x98" /* Ș */ => 'S', "\xC8\x99" /* ș */ => 's',
+ "\xC8\x9A" /* Ț */ => 'T', "\xC8\x9B" /* ț */ => 't',
+ // unmarked
+ "\xC6\xA0" /* Ơ */ => 'O', "\xC6\xA1" /* ơ */ => 'o',
+ "\xC6\xAF" /* Ư */ => 'U', "\xC6\xB0" /* ư */ => 'u',
+ // grave accent
+ "\xE1\xBA\xA6" /* Ầ */ => 'A', "\xE1\xBA\xA7" /* ầ */ => 'a',
+ "\xE1\xBA\xB0" /* Ằ */ => 'A', "\xE1\xBA\xB1" /* ằ */ => 'a',
+ "\xE1\xBB\x80" /* Ề */ => 'E', "\xE1\xBB\x81" /* ề */ => 'e',
+ "\xE1\xBB\x92" /* Ồ */ => 'O', "\xE1\xBB\x93" /* ồ */ => 'o',
+ "\xE1\xBB\x9C" /* Ờ */ => 'O', "\xE1\xBB\x9D" /* ờ */ => 'o',
+ "\xE1\xBB\xAA" /* Ừ */ => 'U', "\xE1\xBB\xAB" /* ừ */ => 'u',
+ "\xE1\xBB\xB2" /* Ỳ */ => 'Y', "\xE1\xBB\xB3" /* ỳ */ => 'y',
+ // hook
+ "\xE1\xBA\xA2" /* Ả */ => 'A', "\xE1\xBA\xA3" /* ả */ => 'a',
+ "\xE1\xBA\xA8" /* Ẩ */ => 'A', "\xE1\xBA\xA9" /* ẩ */ => 'a',
+ "\xE1\xBA\xB2" /* Ẳ */ => 'A', "\xE1\xBA\xB3" /* ẳ */ => 'a',
+ "\xE1\xBA\xBA" /* Ẻ */ => 'E', "\xE1\xBA\xBB" /* ẻ */ => 'e',
+ "\xE1\xBB\x82" /* Ể */ => 'E', "\xE1\xBB\x83" /* ể */ => 'e',
+ "\xE1\xBB\x88" /* Ỉ */ => 'I', "\xE1\xBB\x89" /* ỉ */ => 'i',
+ "\xE1\xBB\x8E" /* Ỏ */ => 'O', "\xE1\xBB\x8F" /* ỏ */ => 'o',
+ "\xE1\xBB\x94" /* Ổ */ => 'O', "\xE1\xBB\x95" /* ổ */ => 'o',
+ "\xE1\xBB\x9E" /* Ở */ => 'O', "\xE1\xBB\x9F" /* ở */ => 'o',
+ "\xE1\xBB\xA6" /* Ủ */ => 'U', "\xE1\xBB\xA7" /* ủ */ => 'u',
+ "\xE1\xBB\xAC" /* Ử */ => 'U', "\xE1\xBB\xAD" /* ử */ => 'u',
+ "\xE1\xBB\xB6" /* Ỷ */ => 'Y', "\xE1\xBB\xB7" /* ỷ */ => 'y',
+ // tilde
+ "\xE1\xBA\xAA" /* Ẫ */ => 'A', "\xE1\xBA\xAB" /* ẫ */ => 'a',
+ "\xE1\xBA\xB4" /* Ẵ */ => 'A', "\xE1\xBA\xB5" /* ẵ */ => 'a',
+ "\xE1\xBA\xBC" /* Ẽ */ => 'E', "\xE1\xBA\xBD" /* ẽ */ => 'e',
+ "\xE1\xBB\x84" /* Ễ */ => 'E', "\xE1\xBB\x85" /* ễ */ => 'e',
+ "\xE1\xBB\x96" /* Ỗ */ => 'O', "\xE1\xBB\x97" /* ỗ */ => 'o',
+ "\xE1\xBB\xA0" /* Ỡ */ => 'O', "\xE1\xBB\xA1" /* ỡ */ => 'o',
+ "\xE1\xBB\xAE" /* Ữ */ => 'U', "\xE1\xBB\xAF" /* ữ */ => 'u',
+ "\xE1\xBB\xB8" /* Ỹ */ => 'Y', "\xE1\xBB\xB9" /* ỹ */ => 'y',
+ // acute accent
+ "\xE1\xBA\xA4" /* Ấ */ => 'A', "\xE1\xBA\xA5" /* ấ */ => 'a',
+ "\xE1\xBA\xAE" /* Ắ */ => 'A', "\xE1\xBA\xAF" /* ắ */ => 'a',
+ "\xE1\xBA\xBE" /* Ế */ => 'E', "\xE1\xBA\xBF" /* ế */ => 'e',
+ "\xE1\xBB\x90" /* Ố */ => 'O', "\xE1\xBB\x91" /* ố */ => 'o',
+ "\xE1\xBB\x9A" /* Ớ */ => 'O', "\xE1\xBB\x9B" /* ớ */ => 'o',
+ "\xE1\xBB\xA8" /* Ứ */ => 'U', "\xE1\xBB\xA9" /* ứ */ => 'u',
+ // dot below
+ "\xE1\xBA\xA0" /* Ạ */ => 'A', "\xE1\xBA\xA1" /* ạ */ => 'a',
+ "\xE1\xBA\xAC" /* Ậ */ => 'A', "\xE1\xBA\xAD" /* ậ */ => 'a',
+ "\xE1\xBA\xB6" /* Ặ */ => 'A', "\xE1\xBA\xB7" /* ặ */ => 'a',
+ "\xE1\xBA\xB8" /* Ẹ */ => 'E', "\xE1\xBA\xB9" /* ẹ */ => 'e',
+ "\xE1\xBB\x86" /* Ệ */ => 'E', "\xE1\xBB\x87" /* ệ */ => 'e',
+ "\xE1\xBB\x8A" /* Ị */ => 'I', "\xE1\xBB\x8B" /* ị */ => 'i',
+ "\xE1\xBB\x8C" /* Ọ */ => 'O', "\xE1\xBB\x8D" /* ọ */ => 'o',
+ "\xE1\xBB\x98" /* Ộ */ => 'O', "\xE1\xBB\x99" /* ộ */ => 'o',
+ "\xE1\xBB\xA2" /* Ợ */ => 'O', "\xE1\xBB\xA3" /* ợ */ => 'o',
+ "\xE1\xBB\xA4" /* Ụ */ => 'U', "\xE1\xBB\xA5" /* ụ */ => 'u',
+ "\xE1\xBB\xB0" /* Ự */ => 'U', "\xE1\xBB\xB1" /* ự */ => 'u',
+ "\xE1\xBB\xB4" /* Ỵ */ => 'Y', "\xE1\xBB\xB5" /* ỵ */ => 'y',
+ );
+ }
+
+ /**
+ * Tests that "normalizer_normalize" exists and works
+ * @return bool
+ */
+ static public function hasNormalizerSupport() {
+ static $ret = null;
+ if (null === $ret) {
+ $form_c = "\xC3\x85"; // 'LATIN CAPITAL LETTER A WITH RING ABOVE' (U+00C5)
+ $form_d = "A\xCC\x8A"; // A followed by 'COMBINING RING ABOVE' (U+030A)
+ $ret = (function_exists('normalizer_normalize')
+ && $form_c === normalizer_normalize($form_d));
+ }
+ return $ret;
+ }
+}
diff --git a/engine/lib/actions.php b/engine/lib/actions.php
index c6613e6d6..53b185dea 100644
--- a/engine/lib/actions.php
+++ b/engine/lib/actions.php
@@ -82,44 +82,28 @@ function action($action, $forwarder = "") {
$forwarder = str_replace(elgg_get_site_url(), "", $forwarder);
$forwarder = str_replace("http://", "", $forwarder);
$forwarder = str_replace("@", "", $forwarder);
-
if (substr($forwarder, 0, 1) == "/") {
$forwarder = substr($forwarder, 1);
}
- if (isset($CONFIG->actions[$action])) {
- if (elgg_is_admin_logged_in() || ($CONFIG->actions[$action]['access'] !== 'admin')) {
- if (elgg_is_logged_in() || ($CONFIG->actions[$action]['access'] === 'public')) {
-
- // Trigger action event
- // @todo This is only called before the primary action is called.
- $event_result = true;
- $event_result = elgg_trigger_plugin_hook('action', $action, null, $event_result);
-
- // Include action
- // Event_result being false doesn't produce an error
- // since i assume this will be handled in the hook itself.
- // @todo make this better!
- if ($event_result) {
- if (!include($CONFIG->actions[$action]['file'])) {
- register_error(elgg_echo('actionnotfound', array($action)));
- }
- }
- } else {
- register_error(elgg_echo('actionloggedout'));
+ if (!isset($CONFIG->actions[$action])) {
+ register_error(elgg_echo('actionundefined', array($action)));
+ } elseif (!elgg_is_admin_logged_in() && ($CONFIG->actions[$action]['access'] === 'admin')) {
+ register_error(elgg_echo('actionunauthorized'));
+ } elseif (!elgg_is_logged_in() && ($CONFIG->actions[$action]['access'] !== 'public')) {
+ register_error(elgg_echo('actionloggedout'));
+ } else {
+ // Returning falsy doesn't produce an error
+ // We assume this will be handled in the hook itself.
+ if (elgg_trigger_plugin_hook('action', $action, null, true)) {
+ if (!include($CONFIG->actions[$action]['file'])) {
+ register_error(elgg_echo('actionnotfound', array($action)));
}
- } else {
- register_error(elgg_echo('actionunauthorized'));
}
- } else {
- register_error(elgg_echo('actionundefined', array($action)));
}
- if (!empty($forwarder)) {
- forward($forwarder);
- } else {
- forward(REFERER);
- }
+ $forwarder = empty($forwarder) ? REFERER : $forwarder;
+ forward($forwarder);
}
/**
@@ -273,8 +257,19 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)
} else if ($visibleerrors) {
register_error(elgg_echo('actiongatekeeper:tokeninvalid'));
}
- } else if ($visibleerrors) {
- register_error(elgg_echo('actiongatekeeper:missingfields'));
+ } else {
+ if (! empty($_SERVER['CONTENT_LENGTH']) && empty($_POST)) {
+ // The size of $_POST or uploaded file has exceed the size limit
+ $error_msg = elgg_trigger_plugin_hook('action_gatekeeper:upload_exceeded_msg', 'all', array(
+ 'post_size' => $_SERVER['CONTENT_LENGTH'],
+ 'visible_errors' => $visibleerrors,
+ ), elgg_echo('actiongatekeeper:uploadexceeded'));
+ } else {
+ $error_msg = elgg_echo('actiongatekeeper:missingfields');
+ }
+ if ($visibleerrors) {
+ register_error($error_msg);
+ }
}
return FALSE;
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index 928101fc5..b65d98c95 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -244,6 +244,7 @@ function admin_init() {
elgg_register_action('profile/fields/delete', '', 'admin');
elgg_register_action('profile/fields/reorder', '', 'admin');
+ elgg_register_simplecache_view('css/admin');
elgg_register_simplecache_view('js/admin');
$url = elgg_get_simplecache_url('js', 'admin');
elgg_register_js('elgg.admin', $url);
@@ -571,7 +572,7 @@ function admin_markdown_page_handler($pages) {
if (!$plugin) {
$error = elgg_echo('admin:plugins:markdown:unknown_plugin');
$body = elgg_view_layout('admin', array('content' => $error, 'title' => $error));
- echo elgg_view_page($title, $body, 'admin');
+ echo elgg_view_page($error, $body, 'admin');
return true;
}
diff --git a/engine/lib/cache.php b/engine/lib/cache.php
index c117b9ec9..be1c43e14 100644
--- a/engine/lib/cache.php
+++ b/engine/lib/cache.php
@@ -442,6 +442,7 @@ function _elgg_cache_init() {
}
if ($CONFIG->system_cache_enabled && !$CONFIG->i18n_loaded_from_cache) {
+ reload_all_translations();
foreach ($CONFIG->translations as $lang => $map) {
elgg_save_system_cache("$lang.php", serialize($map));
}
diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php
index 9bf1529d6..305aa00b6 100644
--- a/engine/lib/configuration.php
+++ b/engine/lib/configuration.php
@@ -476,10 +476,12 @@ function get_config($name, $site_guid = 0) {
break;
}
+ // @todo these haven't really been implemented in Elgg 1.8. Complete in 1.9.
// show dep message
if ($new_name) {
+ // $msg = "Config value $name has been renamed as $new_name";
$name = $new_name;
- elgg_deprecated_notice($msg, $dep_version);
+ // elgg_deprecated_notice($msg, $dep_version);
}
// decide from where to return the value
diff --git a/engine/lib/database.php b/engine/lib/database.php
index cc2b99f6a..7d90b30b8 100644
--- a/engine/lib/database.php
+++ b/engine/lib/database.php
@@ -253,6 +253,10 @@ function execute_query($query, $dblink) {
throw new DatabaseException(elgg_echo('DatabaseException:InvalidQuery'));
}
+ if (!is_resource($dblink)) {
+ throw new DatabaseException(elgg_echo('DatabaseException:InvalidDBLink'));
+ }
+
$dbcalls++;
$result = mysql_query($query, $dblink);
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index b55958a6c..3026a78e3 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -1053,6 +1053,7 @@ function _elgg_php_exception_handler($exception) {
*
* @return true
* @access private
+ * @todo Replace error_log calls with elgg_log calls.
*/
function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
$error = date("Y-m-d H:i:s (T)") . ": \"$errmsg\" in file $filename (line $linenum)";
@@ -1068,6 +1069,7 @@ function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
case E_WARNING :
case E_USER_WARNING :
+ case E_RECOVERABLE_ERROR: // (e.g. type hint violation)
error_log("PHP WARNING: $error");
break;
@@ -1092,8 +1094,8 @@ function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
*
* @note No messages will be displayed unless debugging has been enabled.
*
- * @param str $message User message
- * @param str $level NOTICE | WARNING | ERROR | DEBUG
+ * @param string $message User message
+ * @param string $level NOTICE | WARNING | ERROR | DEBUG
*
* @return bool
* @since 1.7.0
@@ -1263,7 +1265,7 @@ function elgg_deprecated_notice($msg, $dep_version, $backtrace_level = 1) {
$msg .= implode("<br /> -> ", $stack);
- elgg_dump($msg, elgg_is_admin_logged_in(), 'WARNING');
+ elgg_log($msg, 'WARNING');
return true;
}
@@ -1576,7 +1578,11 @@ function elgg_http_url_is_identical($url1, $url2, $ignore_params = array('offset
* @return void
* @since 1.8.0
*/
-function elgg_extract($key, array $array, $default = NULL, $strict = true) {
+function elgg_extract($key, array $array, $default = null, $strict = true) {
+ if (!is_array($array)) {
+ return $default;
+ }
+
if ($strict) {
return (isset($array[$key])) ? $array[$key] : $default;
} else {
@@ -2014,10 +2020,20 @@ function elgg_is_valid_options_for_batch_operation($options, $type) {
*
* @link http://docs.elgg.org/Tutorials/WalledGarden
* @elgg_plugin_hook index system
+ *
+ * @param string $hook The name of the hook
+ * @param string $type The type of hook
+ * @param bool $value Has a plugin already rendered an index page?
+ * @param array $params Array of parameters (should be empty)
* @return bool
* @access private
*/
-function elgg_walled_garden_index() {
+function elgg_walled_garden_index($hook, $type, $value, $params) {
+ if ($value) {
+ // do not create a second index page so return
+ return;
+ }
+
elgg_load_css('elgg.walled_garden');
elgg_load_js('elgg.walled_garden');
@@ -2082,6 +2098,22 @@ function elgg_walled_garden() {
}
/**
+ * Remove public access for walled gardens
+ *
+ * @param string $hook
+ * @param string $type
+ * @param array $accesses
+ * @return array
+ * @access private
+ */
+function _elgg_walled_garden_remove_public_access($hook, $type, $accesses) {
+ if (isset($accesses[ACCESS_PUBLIC])) {
+ unset($accesses[ACCESS_PUBLIC]);
+ }
+ return $accesses;
+}
+
+/**
* Boots the engine
*
* 1. sets error handlers
@@ -2104,11 +2136,13 @@ function _elgg_engine_boot() {
_elgg_load_application_config();
- register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
-
_elgg_load_site_config();
+ _elgg_session_boot();
+
_elgg_load_cache();
+
+ _elgg_load_translations();
}
/**
@@ -2137,6 +2171,7 @@ function elgg_init() {
elgg_register_js('jquery.easing', 'vendors/jquery/jquery.easing.1.3.packed.js');
elgg_register_js('elgg.avatar_cropper', 'js/lib/ui.avatar_cropper.js');
elgg_register_js('jquery.imgareaselect', 'vendors/jquery/jquery.imgareaselect-0.9.8/scripts/jquery.imgareaselect.min.js');
+ elgg_register_js('elgg.ui.river', 'js/lib/ui.river.js');
elgg_register_css('jquery.imgareaselect', 'vendors/jquery/jquery.imgareaselect-0.9.8/css/imgareaselect-deprecated.css');
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index b8ebbd68a..3896cd58f 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -326,6 +326,10 @@ function add_subtype($type, $subtype, $class = "") {
/**
* Removes a registered ElggEntity type, subtype, and classname.
*
+ * @warning You do not want to use this function. If you want to unregister
+ * a class for a subtype, use update_subtype(). Using this function will
+ * permanently orphan all the objects created with the specified subtype.
+ *
* @param string $type Type
* @param string $subtype Subtype
*
@@ -344,7 +348,7 @@ function remove_subtype($type, $subtype) {
}
/**
- * Update a registered ElggEntity type, subtype, and classname
+ * Update a registered ElggEntity type, subtype, and class name
*
* @param string $type Type
* @param string $subtype Subtype
@@ -353,7 +357,7 @@ function remove_subtype($type, $subtype) {
* @return bool
*/
function update_subtype($type, $subtype, $class = '') {
- global $CONFIG;
+ global $CONFIG, $SUBTYPE_CACHE;
if (!$id = get_subtype_id($type, $subtype)) {
return FALSE;
@@ -361,10 +365,16 @@ function update_subtype($type, $subtype, $class = '') {
$type = sanitise_string($type);
$subtype = sanitise_string($subtype);
- return update_data("UPDATE {$CONFIG->dbprefix}entity_subtypes
+ $result = update_data("UPDATE {$CONFIG->dbprefix}entity_subtypes
SET type = '$type', subtype = '$subtype', class = '$class'
WHERE id = $id
");
+
+ if ($result && isset($SUBTYPE_CACHE[$id])) {
+ $SUBTYPE_CACHE[$id]->class = $class;
+ }
+
+ return $result;
}
/**
@@ -943,11 +953,11 @@ function elgg_get_entities(array $options = array()) {
}
if (!$options['count']) {
- if ($options['group_by'] = sanitise_string($options['group_by'])) {
+ if ($options['group_by']) {
$query .= " GROUP BY {$options['group_by']}";
}
- if ($options['order_by'] = sanitise_string($options['order_by'])) {
+ if ($options['order_by']) {
$query .= " ORDER BY {$options['order_by']}";
}
@@ -1493,6 +1503,7 @@ function enable_entity($guid, $recursive = true) {
'relationship' => 'disabled_with',
'relationship_guid' => $entity->guid,
'inverse_relationship' => true,
+ 'limit' => 0,
));
foreach ($disabled_with_it as $e) {
@@ -1808,7 +1819,7 @@ function import_entity_plugin_hook($hook, $entity_type, $returnvalue, $params) {
if ($tmp) {
// Make sure its saved
if (!$tmp->save()) {
- elgg_echo('ImportException:ProblemSaving', array($element->getAttribute('uuid')));
+ $msg = elgg_echo('ImportException:ProblemSaving', array($element->getAttribute('uuid')));
throw new ImportException($msg);
}
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index ffd3c1357..43421342c 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -105,6 +105,7 @@ function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params)
// Save
if (!$entity->save()) {
+ $attr_name = $element->getAttribute('name');
$msg = elgg_echo('ImportException:ProblemUpdatingMeta', array($attr_name, $entity_uuid));
throw new ImportException($msg);
}
@@ -120,7 +121,7 @@ function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params)
* @param string $type 'metadata' or 'annotation'
* @param int $user_guid The GUID of the user
*
- * @return true|false
+ * @return bool
*/
function can_edit_extender($extender_id, $type, $user_guid = 0) {
if (!elgg_is_logged_in()) {
@@ -155,7 +156,7 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
}
// Trigger plugin hooks
- $params = array('entity' => $entity, 'user' => $user);
+ $params = array('entity' => $extender->getEntity(), 'user' => $user);
return elgg_trigger_plugin_hook('permissions_check', $type, $params, false);
}
diff --git a/engine/lib/filestore.php b/engine/lib/filestore.php
index 86f6d9baa..93a127257 100644
--- a/engine/lib/filestore.php
+++ b/engine/lib/filestore.php
@@ -149,6 +149,12 @@ $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0, $upscale = FALSE) {
return FALSE;
}
+ // color transparencies white (default is black)
+ imagefilledrectangle(
+ $new_image, 0, 0, $params['newwidth'], $params['newheight'],
+ imagecolorallocate($new_image, 255, 255, 255)
+ );
+
$rtn_code = imagecopyresampled( $new_image,
$original_image,
0,
diff --git a/engine/lib/input.php b/engine/lib/input.php
index dda8211b6..6d1646e1a 100644
--- a/engine/lib/input.php
+++ b/engine/lib/input.php
@@ -283,7 +283,7 @@ function input_livesearch_page_handler($page) {
WHERE e.guid = ue.guid
AND e.enabled = 'yes'
AND ue.banned = 'no'
- AND (ue.name LIKE '$q%' OR ue.username LIKE '$q%')
+ AND (ue.name LIKE '$q%' OR ue.name LIKE '% $q%' OR ue.username LIKE '$q%')
LIMIT $limit
";
@@ -333,7 +333,7 @@ function input_livesearch_page_handler($page) {
WHERE e.guid = ge.guid
AND e.enabled = 'yes'
$owner_where
- AND (ge.name LIKE '$q%' OR ge.description LIKE '%$q%')
+ AND (ge.name LIKE '$q%' OR ge.name LIKE '% $q%' OR ge.description LIKE '% $q%')
LIMIT $limit
";
if ($entities = get_data($query)) {
@@ -379,7 +379,7 @@ function input_livesearch_page_handler($page) {
AND e.guid = ue.guid
AND e.enabled = 'yes'
AND ue.banned = 'no'
- AND (ue.name LIKE '$q%' OR ue.username LIKE '$q%')
+ AND (ue.name LIKE '$q%' OR ue.name LIKE '% $q%' OR ue.username LIKE '$q%')
LIMIT $limit
";
diff --git a/engine/lib/languages.php b/engine/lib/languages.php
index 7a508d298..98006f7cd 100644
--- a/engine/lib/languages.php
+++ b/engine/lib/languages.php
@@ -8,6 +8,65 @@
*/
/**
+ * Given a message key, returns an appropriately translated full-text string
+ *
+ * @param string $message_key The short message code
+ * @param array $args An array of arguments to pass through vsprintf().
+ * @param string $language Optionally, the standard language code
+ * (defaults to site/user default, then English)
+ *
+ * @return string Either the translated string, the English string,
+ * or the original language string.
+ */
+function elgg_echo($message_key, $args = array(), $language = "") {
+ global $CONFIG;
+
+ static $CURRENT_LANGUAGE;
+
+ // old param order is deprecated
+ if (!is_array($args)) {
+ elgg_deprecated_notice(
+ 'As of Elgg 1.8, the 2nd arg to elgg_echo() is an array of string replacements and the 3rd arg is the language.',
+ 1.8
+ );
+
+ $language = $args;
+ $args = array();
+ }
+
+ if (!isset($CONFIG->translations)) {
+ // this means we probably had an exception before translations were initialized
+ register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
+ }
+
+ if (!$CURRENT_LANGUAGE) {
+ $CURRENT_LANGUAGE = get_language();
+ }
+ if (!$language) {
+ $language = $CURRENT_LANGUAGE;
+ }
+
+ if (isset($CONFIG->translations[$language][$message_key])) {
+ $string = $CONFIG->translations[$language][$message_key];
+ } else if (isset($CONFIG->translations["en"][$message_key])) {
+ $string = $CONFIG->translations["en"][$message_key];
+ $lang = $CONFIG->translations["en"][$language];
+ elgg_log(sprintf('Missing %s translation for "%s" language key', $lang, $message_key), 'NOTICE');
+ } else {
+ $string = $message_key;
+ elgg_log(sprintf('Missing English translation for "%s" language key', $message_key), 'NOTICE');
+ }
+
+ // only pass through if we have arguments to allow backward compatibility
+ // with manual sprintf() calls.
+ if ($args) {
+ $string = vsprintf($string, $args);
+ }
+
+ return $string;
+}
+
+/**
* Add a translation.
*
* Translations are arrays in the Zend Translation array format, eg:
@@ -82,56 +141,34 @@ function get_language() {
return false;
}
-/**
- * Given a message shortcode, returns an appropriately translated full-text string
- *
- * @param string $message_key The short message code
- * @param array $args An array of arguments to pass through vsprintf().
- * @param string $language Optionally, the standard language code
- * (defaults to site/user default, then English)
- *
- * @return string Either the translated string, the English string,
- * or the original language string.
- */
-function elgg_echo($message_key, $args = array(), $language = "") {
+function _elgg_load_translations() {
global $CONFIG;
- static $CURRENT_LANGUAGE;
-
- // old param order is deprecated
- if (!is_array($args)) {
- elgg_deprecated_notice(
- 'As of Elgg 1.8, the 2nd arg to elgg_echo() is an array of string replacements and the 3rd arg is the language.',
- 1.8
- );
-
- $language = $args;
- $args = array();
- }
+ if ($CONFIG->system_cache_enabled) {
+ $loaded = true;
+ $languages = array_unique(array('en', get_current_language()));
+ foreach ($languages as $language) {
+ $data = elgg_load_system_cache("$language.php");
+ if ($data) {
+ add_translation($language, unserialize($data));
+ } else {
+ $loaded = false;
+ }
+ }
- if (!$CURRENT_LANGUAGE) {
- $CURRENT_LANGUAGE = get_language();
- }
- if (!$language) {
- $language = $CURRENT_LANGUAGE;
+ if ($loaded) {
+ $CONFIG->i18n_loaded_from_cache = true;
+ // this is here to force
+ $CONFIG->language_paths[dirname(dirname(dirname(__FILE__))) . "/languages/"] = true;
+ return;
+ }
}
- if (isset($CONFIG->translations[$language][$message_key])) {
- $string = $CONFIG->translations[$language][$message_key];
- } else if (isset($CONFIG->translations["en"][$message_key])) {
- $string = $CONFIG->translations["en"][$message_key];
- } else {
- $string = $message_key;
- }
+ // load core translations from languages directory
+ register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
+}
- // only pass through if we have arguments to allow backward compatibility
- // with manual sprintf() calls.
- if ($args) {
- $string = vsprintf($string, $args);
- }
- return $string;
-}
/**
* When given a full path, finds translation files and loads them
@@ -145,16 +182,9 @@ function elgg_echo($message_key, $args = array(), $language = "") {
function register_translations($path, $load_all = false) {
global $CONFIG;
- static $load_from_cache;
- static $cache_loaded_langs;
- if (!isset($load_from_cache)) {
- $load_from_cache = $CONFIG->system_cache_enabled;
- $cache_loaded_langs = array();
- }
-
$path = sanitise_filepath($path);
- // Make a note of this path just in case we need to register this language later
+ // Make a note of this path just incase we need to register this language later
if (!isset($CONFIG->language_paths)) {
$CONFIG->language_paths = array();
}
@@ -162,6 +192,7 @@ function register_translations($path, $load_all = false) {
// Get the current language based on site defaults and user preference
$current_language = get_current_language();
+ elgg_log("Translations loaded from: $path");
// only load these files unless $load_all is true.
$load_language_files = array(
@@ -171,32 +202,6 @@ function register_translations($path, $load_all = false) {
$load_language_files = array_unique($load_language_files);
- if ($load_from_cache && !$load_all) {
- // load language files from cache
- $data = array();
- foreach ($load_language_files as $lang_file) {
- $lang = substr($lang_file, 0, strpos($lang_file, '.'));
- if (!isset($cache_loaded_langs[$lang])) {
- $data[$lang] = elgg_load_system_cache($lang_file);
- if ($data[$lang]) {
- $cache_loaded_langs[$lang] = true;
- } else {
- // this language file not cached yet
- $load_from_cache = false;
- }
- }
- }
-
- // are we still suppose to load from cache
- if ($load_from_cache) {
- foreach ($data as $lang => $map) {
- add_translation($lang, unserialize($map));
- }
- $CONFIG->i18n_loaded_from_cache = true;
- return true;
- }
- }
-
$handle = opendir($path);
if (!$handle) {
elgg_log("Could not open language path: $path", 'ERROR');
@@ -218,11 +223,6 @@ function register_translations($path, $load_all = false) {
}
}
- elgg_log("Translations loaded from: $path");
-
- // make sure caching code saves language data if system cache is on
- $CONFIG->i18n_loaded_from_cache = false;
-
return $return;
}
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index 0ff3a43dc..77fa30e41 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -361,13 +361,24 @@ function elgg_enable_metadata(array $options) {
* options available to elgg_get_entities(). Supports
* the singular option shortcut.
*
- * NB: Using metadata_names and metadata_values results in a
+ * @note Using metadata_names and metadata_values results in a
* "names IN (...) AND values IN (...)" clause. This is subtly
* differently than default multiple metadata_name_value_pairs, which use
* "(name = value) AND (name = value)" clauses.
*
* When in doubt, use name_value_pairs.
*
+ * To ask for entities that do not have a metadata value, use a custom
+ * where clause like this:
+ *
+ * $options['wheres'][] = "NOT EXISTS (
+ * SELECT 1 FROM {$dbprefix}metadata md
+ * WHERE md.entity_guid = e.guid
+ * AND md.name_id = $name_metastring_id
+ * AND md.value_id = $value_metastring_id)";
+ *
+ * Note the metadata name and value has been denormalized in the above example.
+ *
* @see elgg_get_entities
*
* @param array $options Array in format:
diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php
index a7984ce5a..10b11acfe 100644
--- a/engine/lib/navigation.php
+++ b/engine/lib/navigation.php
@@ -230,7 +230,7 @@ function elgg_pop_breadcrumb() {
global $CONFIG;
if (is_array($CONFIG->breadcrumbs)) {
- array_pop($CONFIG->breadcrumbs);
+ return array_pop($CONFIG->breadcrumbs);
}
return FALSE;
@@ -335,6 +335,19 @@ function elgg_river_menu_setup($hook, $type, $return, $params) {
$return[] = ElggMenuItem::factory($options);
}
}
+
+ if (elgg_is_admin_logged_in()) {
+ $options = array(
+ 'name' => 'delete',
+ 'href' => "action/river/delete?id=$item->id",
+ 'text' => elgg_view_icon('delete'),
+ 'title' => elgg_echo('delete'),
+ 'confirm' => elgg_echo('deleteconfirm'),
+ 'is_action' => true,
+ 'priority' => 200,
+ );
+ $return[] = ElggMenuItem::factory($options);
+ }
}
return $return;
diff --git a/engine/lib/notification.php b/engine/lib/notification.php
index 5a2f5f8ac..18faff27f 100644
--- a/engine/lib/notification.php
+++ b/engine/lib/notification.php
@@ -480,8 +480,8 @@ function object_notifications($event, $object_type, $object) {
}
if (isset($CONFIG->register_objects[$object_type][$object_subtype])) {
- $descr = $CONFIG->register_objects[$object_type][$object_subtype];
- $string = $descr . ": " . $object->getURL();
+ $subject = $CONFIG->register_objects[$object_type][$object_subtype];
+ $string = $subject . ": " . $object->getURL();
// Get users interested in content from this person and notify them
// (Person defined by container_guid so we can also subscribe to groups if we want)
@@ -500,16 +500,16 @@ function object_notifications($event, $object_type, $object) {
if ($user instanceof ElggUser && !$user->isBanned()) {
if (($user->guid != $SESSION['user']->guid) && has_access_to_entity($object, $user)
&& $object->access_id != ACCESS_PRIVATE) {
- $methodstring = elgg_trigger_plugin_hook('notify:entity:message', $object->getType(), array(
+ $body = elgg_trigger_plugin_hook('notify:entity:message', $object->getType(), array(
'entity' => $object,
'to_entity' => $user,
'method' => $method), $string);
- if (empty($methodstring) && $methodstring !== false) {
- $methodstring = $string;
+ if (empty($body) && $body !== false) {
+ $body = $string;
}
- if ($methodstring !== false) {
- notify_user($user->guid, $object->container_guid, $descr, $methodstring,
- NULL, array($method));
+ if ($body !== false) {
+ notify_user($user->guid, $object->container_guid, $subject, $body,
+ null, array($method));
}
}
}
diff --git a/engine/lib/output.php b/engine/lib/output.php
index b1245a924..7bfc4be6e 100644
--- a/engine/lib/output.php
+++ b/engine/lib/output.php
@@ -310,19 +310,11 @@ function elgg_get_friendly_title($title) {
return $result;
}
- // @todo not using this because of locale concerns
- //$title = iconv('UTF-8', 'ASCII//TRANSLIT', $title);
-
- // @todo this uses a utf8 character class. can use if
- // we want to support utf8 in the url.
- //$title = preg_replace('/[^\p{L}\- ]/u', '', $title);
-
- // use A-Za-z0-9_ instead of \w because \w is locale sensitive
- $title = preg_replace("/[^A-Za-z0-9_\- ]/", "", $title);
- $title = str_replace(" ", "-", $title);
- $title = str_replace("--", "-", $title);
- $title = trim($title);
- $title = elgg_strtolower($title);
+ // handle some special cases
+ $title = str_replace('&amp;', 'and', $title);
+
+ $title = ElggTranslit::urlize($title);
+
return $title;
}
diff --git a/engine/lib/pagehandler.php b/engine/lib/pagehandler.php
index a675d976a..ba7518a77 100644
--- a/engine/lib/pagehandler.php
+++ b/engine/lib/pagehandler.php
@@ -31,18 +31,18 @@ function page_handler($handler, $page) {
}
// return false to stop processing the request (because you handled it)
- // return a new $params array if you want to route the request differently
- $params = array(
+ // return a new $request array if you want to route the request differently
+ $request = array(
'handler' => $handler,
'segments' => $page,
);
- $params = elgg_trigger_plugin_hook('route', $handler, NULL, $params);
- if ($params === false) {
+ $request = elgg_trigger_plugin_hook('route', $handler, null, $request);
+ if ($request === false) {
return true;
}
- $handler = $params['handler'];
- $page = $params['segments'];
+ $handler = $request['handler'];
+ $page = $request['segments'];
$result = false;
if (isset($CONFIG->pagehandler) && !empty($handler) && isset($CONFIG->pagehandler[$handler])) {
@@ -129,7 +129,7 @@ function elgg_error_page_handler($hook, $type, $result, $params) {
$content = elgg_view("errors/default", $params);
}
$body = elgg_view_layout('error', array('content' => $content));
- echo elgg_view_page($title, $body, 'error');
+ echo elgg_view_page('', $body, 'error');
exit;
}
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index 39a76db5d..d5cd4fe76 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -311,6 +311,10 @@ function elgg_load_plugins() {
$start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_VIEWS;
}
+ if (elgg_get_config('i18n_loaded_from_cache')) {
+ $start_flags = $start_flags & ~ELGG_PLUGIN_REGISTER_LANGUAGES;
+ }
+
$return = true;
$plugins = elgg_get_plugins('active');
if ($plugins) {
diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php
index f50c4a485..09d541e22 100644
--- a/engine/lib/relationships.php
+++ b/engine/lib/relationships.php
@@ -239,6 +239,15 @@ function get_entity_relationships($guid, $inverse_relationship = FALSE) {
* Also accepts all options available to elgg_get_entities() and
* elgg_get_entities_from_metadata().
*
+ * To ask for entities that do not have a particulat relationship to an entity,
+ * use a custom where clause like the following:
+ *
+ * $options['wheres'][] = "NOT EXISTS (
+ * SELECT 1 FROM {$db_prefix}entity_relationships
+ * WHERE guid_one = e.guid
+ * AND relationship = '$relationship'
+ * )";
+ *
* @see elgg_get_entities
* @see elgg_get_entities_from_metadata
*
diff --git a/engine/lib/river.php b/engine/lib/river.php
index 547d9495e..b717a7756 100644
--- a/engine/lib/river.php
+++ b/engine/lib/river.php
@@ -55,7 +55,7 @@ $posted = 0, $annotation_id = 0) {
$posted = sanitise_int($posted);
$annotation_id = sanitise_int($annotation_id);
- $params = array(
+ $values = array(
'type' => $type,
'subtype' => $subtype,
'action_type' => $action_type,
@@ -68,13 +68,13 @@ $posted = 0, $annotation_id = 0) {
);
// return false to stop insert
- $params = elgg_trigger_plugin_hook('creating', 'river', null, $params);
- if ($params == false) {
+ $values = elgg_trigger_plugin_hook('creating', 'river', null, $values);
+ if ($values == false) {
// inserting did not fail - it was just prevented
return true;
}
- extract($params);
+ extract($values);
// Attempt to save river item; return success status
$id = insert_data("insert into {$CONFIG->dbprefix}river " .
@@ -643,9 +643,11 @@ function elgg_river_init() {
elgg_register_page_handler('activity', 'elgg_river_page_handler');
$item = new ElggMenuItem('activity', elgg_echo('activity'), 'activity');
elgg_register_menu_item('site', $item);
-
+
elgg_register_widget_type('river_widget', elgg_echo('river:widget:title'), elgg_echo('river:widget:description'));
+ elgg_register_action('river/delete', '', 'admin');
+
elgg_register_plugin_hook_handler('unit_test', 'system', 'elgg_river_test');
}
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php
index 419d36707..72ca0a1c2 100644
--- a/engine/lib/sessions.php
+++ b/engine/lib/sessions.php
@@ -376,14 +376,10 @@ function logout() {
*
* @uses $_SESSION
*
- * @param string $event Event name
- * @param string $object_type Object type
- * @param mixed $object Object
- *
* @return bool
* @access private
*/
-function _elgg_session_boot($event, $object_type, $object) {
+function _elgg_session_boot() {
global $DB_PREFIX, $CONFIG;
// Use database for sessions
@@ -464,9 +460,6 @@ function _elgg_session_boot($event, $object_type, $object) {
return false;
}
- // Since we have loaded a new user, this user may have different language preferences
- register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
-
return true;
}
@@ -658,5 +651,3 @@ function _elgg_session_gc($maxlifetime) {
return true;
}
-
-elgg_register_event_handler('boot', 'system', '_elgg_session_boot', 2);
diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php
index e1f95ed97..5ee640549 100644
--- a/engine/lib/statistics.php
+++ b/engine/lib/statistics.php
@@ -95,8 +95,8 @@ function get_number_users($show_deactivated = false) {
* @return string
*/
function get_online_users() {
- $count = find_active_users(600, 10, $offset, true);
- $objects = find_active_users(600, 10, $offset);
+ $count = find_active_users(600, 10, 0, true);
+ $objects = find_active_users(600, 10);
if ($objects) {
return elgg_view_entity_list($objects, array(
diff --git a/engine/lib/system_log.php b/engine/lib/system_log.php
index 28d90be56..53fa24557 100644
--- a/engine/lib/system_log.php
+++ b/engine/lib/system_log.php
@@ -156,9 +156,8 @@ function get_object_from_log_entry($entry_id) {
* This is called by the event system and should not be called directly.
*
* @param object $object The object you're talking about.
- * @param string $event String The event being logged
- *
- * @return mixed
+ * @param string $event The event being logged
+ * @return void
*/
function system_log($object, $event) {
global $CONFIG;
@@ -166,6 +165,12 @@ function system_log($object, $event) {
static $cache_size = 0;
if ($object instanceof Loggable) {
+
+ if (datalist_get('version') < 2012012000) {
+ // this is a site that doesn't have the ip_address column yet
+ return;
+ }
+
// reset cache if it has grown too large
if (!is_array($log_cache) || $cache_size > 500) {
$log_cache = array();
@@ -213,8 +218,6 @@ function system_log($object, $event) {
$log_cache[$time][$object_id][$event] = true;
$cache_size += 1;
}
-
- return true;
}
}
diff --git a/engine/lib/users.php b/engine/lib/users.php
index e209f2c38..527eff3cd 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -136,7 +136,6 @@ function ban_user($user_guid, $reason = "") {
global $CONFIG;
$user_guid = (int)$user_guid;
- $reason = sanitise_string($reason);
$user = get_entity($user_guid);
@@ -810,6 +809,12 @@ function validate_username($username) {
$msg = elgg_echo('registration:usernametooshort', array($CONFIG->minusername));
throw new RegistrationException($msg);
}
+
+ // username in the database has a limit of 128 characters
+ if (strlen($username) > 128) {
+ $msg = elgg_echo('registration:usernametoolong', array(128));
+ throw new RegistrationException($msg);
+ }
// Blacklist for bad characters (partially nicked from mediawiki)
$blacklist = '/[' .
@@ -1556,7 +1561,7 @@ function users_init() {
elgg_register_action('friends/remove');
elgg_register_action('avatar/upload');
elgg_register_action('avatar/crop');
- elgg_register_action('avatar/revert');
+ elgg_register_action('avatar/remove');
elgg_register_action('profile/edit');
elgg_register_action('friends/collections/add');
diff --git a/engine/lib/views.php b/engine/lib/views.php
index 1b013be6f..b00334062 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -303,7 +303,7 @@ function elgg_set_view_location($view, $location, $viewtype = '') {
/**
* Returns whether the specified view exists
*
- * @note If $recurse is strue, also checks if a view exists only as an extension.
+ * @note If $recurse is true, also checks if a view exists only as an extension.
*
* @param string $view The view name
* @param string $viewtype If set, forces the viewtype
@@ -403,7 +403,7 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
$view_orig = $view;
// Trigger the pagesetup event
- if (!isset($CONFIG->pagesetupdone)) {
+ if (!isset($CONFIG->pagesetupdone) && $CONFIG->boot_complete) {
$CONFIG->pagesetupdone = true;
elgg_trigger_event('pagesetup', 'system');
}
@@ -1224,12 +1224,12 @@ function elgg_view_image_block($image, $body, $vars = array()) {
* @param string $type The type of module (main, info, popup, aside, etc.)
* @param string $title A title to put in the header
* @param string $body Content of the module
- * @param string $vars Additional parameters for the module
+ * @param array $vars Additional parameters for the module
*
* @return string
* @since 1.8.0
*/
-function elgg_view_module($type, $title, $body, $vars = array()) {
+function elgg_view_module($type, $title, $body, array $vars = array()) {
$vars['class'] = elgg_extract('class', $vars, '') . " elgg-module-$type";
$vars['title'] = $title;
diff --git a/engine/start.php b/engine/start.php
index 506e27380..55b8ffa5b 100644
--- a/engine/start.php
+++ b/engine/start.php
@@ -49,6 +49,7 @@ global $CONFIG;
if (!isset($CONFIG)) {
$CONFIG = new stdClass;
}
+$CONFIG->boot_complete = false;
$lib_dir = dirname(__FILE__) . '/lib/';
@@ -99,11 +100,22 @@ elgg_trigger_event('boot', 'system');
// Load the plugins that are active
elgg_load_plugins();
+
+// @todo move loading plugins into a single boot function that replaces 'boot', 'system' event
+// and then move this code in there.
+// This validates the view type - first opportunity to do it is after plugins load.
+$view_type = elgg_get_viewtype();
+if (!elgg_is_valid_view_type($view_type)) {
+ elgg_set_viewtype('default');
+}
+
// @todo deprecate as plugins can use 'init', 'system' event
elgg_trigger_event('plugins_boot', 'system');
// Complete the boot process for both engine and plugins
elgg_trigger_event('init', 'system');
+$CONFIG->boot_complete = true;
+
// System loaded and ready
elgg_trigger_event('ready', 'system');
diff --git a/engine/tests/api/metadata.php b/engine/tests/api/metadata.php
index 2461e975e..9933263d1 100644
--- a/engine/tests/api/metadata.php
+++ b/engine/tests/api/metadata.php
@@ -28,6 +28,9 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
public function testGetMetastringById() {
foreach (array('metaUnitTest', 'metaunittest', 'METAUNITTEST') as $string) {
+ // since there is no guarantee that metastrings are garbage collected
+ // between unit test runs, we delete before testing
+ $this->delete_metastrings($string);
$this->create_metastring($string);
}
@@ -43,9 +46,6 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
{
$this->assertTrue(in_array($string, $this->metastrings));
}
-
- // clean up
- $this->delete_metastrings();
}
public function testElggGetEntitiesFromMetadata() {
@@ -77,7 +77,6 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
// clean up
$this->object->delete();
- $this->delete_metastrings();
}
public function testElggGetMetadataCount() {
@@ -198,20 +197,20 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
$u2->delete();
}
-
- protected function create_metastring($string) {
+ protected function delete_metastrings($string) {
global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
$METASTRINGS_CACHE = $METASTRINGS_DEADNAME_CACHE = array();
- mysql_query("INSERT INTO {$CONFIG->dbprefix}metastrings (string) VALUES ('$string')");
- $this->metastrings[$string] = mysql_insert_id();
+ $string = sanitise_string($string);
+ mysql_query("DELETE FROM {$CONFIG->dbprefix}metastrings WHERE string = BINARY '$string'");
}
- protected function delete_metastrings() {
+ protected function create_metastring($string) {
global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
$METASTRINGS_CACHE = $METASTRINGS_DEADNAME_CACHE = array();
- $strings = implode(', ', $this->metastrings);
- mysql_query("DELETE FROM {$CONFIG->dbprefix}metastrings WHERE id IN ($strings)");
+ $string = sanitise_string($string);
+ mysql_query("INSERT INTO {$CONFIG->dbprefix}metastrings (string) VALUES ('$string')");
+ $this->metastrings[$string] = mysql_insert_id();
}
}
diff --git a/engine/tests/api/plugins.php b/engine/tests/api/plugins.php
index 8ecb0a46c..114f3991b 100644
--- a/engine/tests/api/plugins.php
+++ b/engine/tests/api/plugins.php
@@ -68,6 +68,9 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest {
'blurb' => 'A concise description.',
'description' => 'A longer, more interesting description.',
'website' => 'http://www.elgg.org/',
+ 'repository' => 'https://github.com/Elgg/Elgg',
+ 'bugtracker' => 'http://trac.elgg.org',
+ 'donations' => 'http://elgg.org/supporter.php',
'copyright' => '(C) Elgg Foundation 2011',
'license' => 'GNU General Public License version 2',
@@ -164,6 +167,21 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest {
$this->assertEqual($this->manifest18->getWebsite(), 'http://www.elgg.org/');
$this->assertEqual($this->manifest17->getWebsite(), 'http://www.elgg.org/');
}
+
+ public function testElggPluginManifestGetRepository() {
+ $this->assertEqual($this->manifest18->getRepositoryURL(), 'https://github.com/Elgg/Elgg');
+ $this->assertEqual($this->manifest17->getRepositoryURL(), '');
+ }
+
+ public function testElggPluginManifestGetBugtracker() {
+ $this->assertEqual($this->manifest18->getBugTrackerURL(), 'http://trac.elgg.org');
+ $this->assertEqual($this->manifest17->getBugTrackerURL(), '');
+ }
+
+ public function testElggPluginManifestGetDonationsPage() {
+ $this->assertEqual($this->manifest18->getDonationsPageURL(), 'http://elgg.org/supporter.php');
+ $this->assertEqual($this->manifest17->getDonationsPageURL(), '');
+ }
public function testElggPluginManifestGetCopyright() {
$this->assertEqual($this->manifest18->getCopyright(), '(C) Elgg Foundation 2011');
diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php
index 26a45ab6a..691433a41 100644
--- a/engine/tests/regression/trac_bugs.php
+++ b/engine/tests/regression/trac_bugs.php
@@ -202,16 +202,33 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest {
/**
* http://trac.elgg.org/ticket/3210 - Don't remove -s in friendly titles
- * @todo: http://trac.elgg.org/ticket/2276 - improve char encoding
+ * http://trac.elgg.org/ticket/2276 - improve char encoding
*/
public function test_friendly_title() {
$cases = array(
- 'Simple Test' => 'simple-test',
- 'Test top-level page' => 'test-top-level-page',
-// 'éclair' => 'éclair',
-// 'English, Español, and 日本語' => 'english-español-and-日本語'
+ // hyphen, underscore and ASCII whitespace replaced by separator,
+ // other non-alphanumeric ASCII removed
+ "a-a_a a\na\ra\ta\va!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-a-a-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+
+ // separators trimmed
+ "-_ hello _-" => "hello",
+
+ // accents removed, lower case, other multibyte chars are URL encoded
+ "I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n, AND \xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"
+ // Iñtërnâtiônàlizætiøn, AND 日本語
+ => 'internationalizaetion-and-%E6%97%A5%E6%9C%AC%E8%AA%9E',
+
+ // some HTML entity replacements
+ "Me &amp; You" => 'me-and-you',
);
+ // where available, string is converted to NFC before transliteration
+ if (ElggTranslit::hasNormalizerSupport()) {
+ $form_d = "A\xCC\x8A"; // A followed by 'COMBINING RING ABOVE' (U+030A)
+ $cases[$form_d] = "a";
+ }
+
foreach ($cases as $case => $expected) {
$friendly_title = elgg_get_friendly_title($case);
$this->assertIdentical($expected, $friendly_title);
diff --git a/engine/tests/test_files/plugin_18/manifest.xml b/engine/tests/test_files/plugin_18/manifest.xml
index 9654b6422..5d788616a 100644
--- a/engine/tests/test_files/plugin_18/manifest.xml
+++ b/engine/tests/test_files/plugin_18/manifest.xml
@@ -6,6 +6,9 @@
<blurb>A concise description.</blurb>
<description>A longer, more interesting description.</description>
<website>http://www.elgg.org/</website>
+ <repository>https://github.com/Elgg/Elgg</repository>
+ <bugtracker>http://trac.elgg.org</bugtracker>
+ <donations>http://elgg.org/supporter.php</donations>
<copyright>(C) Elgg Foundation 2011</copyright>
<license>GNU General Public License version 2</license>