aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt77
-rw-r--r--CONTRIBUTORS.txt5
-rw-r--r--actions/profile/edit.php4
-rw-r--r--actions/register.php5
-rw-r--r--engine/classes/ElggAutoP.php309
-rw-r--r--engine/classes/ElggPAM.php8
-rw-r--r--engine/classes/ElggPlugin.php7
-rw-r--r--engine/classes/ElggPluginManifest.php2
-rw-r--r--engine/classes/ElggPluginManifestParser.php6
-rw-r--r--engine/classes/ElggVolatileMetadataCache.php3
-rw-r--r--engine/classes/ElggXMLElement.php115
-rw-r--r--engine/handlers/cache_handler.php6
-rw-r--r--engine/lib/access.php11
-rw-r--r--engine/lib/admin.php5
-rw-r--r--engine/lib/configuration.php26
-rw-r--r--engine/lib/elgglib.php56
-rw-r--r--engine/lib/entities.php210
-rw-r--r--engine/lib/extender.php9
-rw-r--r--engine/lib/group.php1
-rw-r--r--engine/lib/notification.php7
-rw-r--r--engine/lib/objects.php1
-rw-r--r--engine/lib/output.php130
-rw-r--r--engine/lib/pagehandler.php10
-rw-r--r--engine/lib/pam.php7
-rw-r--r--engine/lib/plugins.php21
-rw-r--r--engine/lib/relationships.php2
-rw-r--r--engine/lib/river.php48
-rw-r--r--engine/lib/sites.php1
-rw-r--r--engine/lib/upgrades/2010052601.php12
-rw-r--r--engine/lib/users.php1
-rw-r--r--engine/lib/views.php148
-rw-r--r--engine/lib/web_services.php44
-rw-r--r--engine/lib/xml.php38
-rw-r--r--engine/tests/api/metadata.php6
-rw-r--r--engine/tests/api/output.php74
-rw-r--r--engine/tests/test_files/output/autop/block-a.exp.norun.html6
-rw-r--r--engine/tests/test_files/output/autop/block-a.in.norun.html9
-rw-r--r--engine/tests/test_files/output/autop/domdoc_exp.html46
-rw-r--r--engine/tests/test_files/output/autop/domdoc_in.html80
-rw-r--r--engine/tests/test_files/output/autop/typical-post.exp.html84
-rw-r--r--engine/tests/test_files/output/autop/typical-post.in.html89
-rw-r--r--engine/tests/test_files/output/autop/wp-welcome.exp.html22
-rw-r--r--engine/tests/test_files/output/autop/wp-welcome.in.html25
-rw-r--r--engine/tests/test_files/output/autop/wpautop-fails.exp.html31
-rw-r--r--engine/tests/test_files/output/autop/wpautop-fails.in.html41
-rw-r--r--engine/tests/test_files/output/autop/wysiwyg-test.exp.html51
-rw-r--r--engine/tests/test_files/output/autop/wysiwyg-test.in.html79
-rw-r--r--install/ElggInstaller.php2
-rw-r--r--install/cli/sample_installer.php35
-rw-r--r--js/lib/ui.js2
-rw-r--r--js/tests/ElggLibTest.js2
-rw-r--r--languages/en.php3
-rw-r--r--mod/blog/lib/blog.php91
-rw-r--r--mod/blog/start.php3
-rw-r--r--mod/blog/views/default/forms/blog/save.php4
-rw-r--r--mod/file/thumbnail.php2
-rw-r--r--mod/groups/actions/groups/edit.php143
-rw-r--r--mod/groups/icon.php6
-rw-r--r--mod/groups/languages/en.php1
-rw-r--r--mod/groups/views/default/forms/groups/edit.php40
-rw-r--r--mod/groups/views/default/groups/js.php7
-rw-r--r--mod/groups/views/rss/groups/profile/layout.php13
-rw-r--r--mod/groups/views/rss/object/groupforumtopic.php2
-rw-r--r--mod/messageboard/views/default/river/object/messageboard/create.php23
-rw-r--r--mod/messages/pages/messages/read.php4
-rw-r--r--mod/profile/icondirect.php18
-rw-r--r--mod/profile/views/default/profile/details.php2
-rw-r--r--mod/search/views/default/search/no_results.php2
-rw-r--r--mod/thewire/views/rss/object/thewire.php2
-rw-r--r--mod/twitter/views/default/widgets/twitter/content.php2
-rw-r--r--mod/twitter_api/vendors/twitteroauth/OAuth.php3
-rw-r--r--mod/twitter_api/vendors/twitteroauth/twitterOAuth.php4
-rw-r--r--mod/uservalidationbyemail/start.php16
-rw-r--r--mod/uservalidationbyemail/views/default/forms/uservalidationbyemail/bulk_action.php2
-rw-r--r--pages/avatar/view.php2
-rw-r--r--version.php4
-rw-r--r--views/default/admin/users/admins.php12
-rw-r--r--views/default/css/admin.php4
-rw-r--r--views/default/forms/profile/fields/add.php2
-rw-r--r--views/default/forms/user/passwordreset.php2
-rw-r--r--views/default/js/admin.php11
-rw-r--r--views/default/js/elgg.php1
-rw-r--r--views/default/js/initialize_elgg.php1
-rw-r--r--views/default/js/lightbox.php1
-rw-r--r--views/default/js/walled_garden.php5
-rw-r--r--views/default/output/email.php4
-rw-r--r--views/default/output/longtext.php2
-rw-r--r--views/default/page/elements/messages.php2
-rw-r--r--views/installation/install/pages/admin.php2
-rw-r--r--views/installation/install/pages/complete.php2
-rw-r--r--views/installation/install/pages/database.php4
-rw-r--r--views/installation/install/pages/requirements.php4
-rw-r--r--views/installation/install/pages/settings.php2
-rw-r--r--views/installation/install/pages/welcome.php2
-rw-r--r--views/installation/page/elements/messages.php2
-rw-r--r--views/opendd/messages/exceptions/exception.php2
-rw-r--r--views/rss/group/default.php4
-rw-r--r--views/rss/object/default.php2
-rw-r--r--views/rss/user/default.php2
-rw-r--r--views/xml/messages/exceptions/exception.php2
100 files changed, 1974 insertions, 521 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 7a3422d7d..ca1bdc675 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,80 @@
+Version 1.8.11
+(December 5th, 2012 from https://github.com/Elgg/Elgg/tree/1.8)
+
+ Bugfix:
+ * Fixed fatal error in group creation form
+
+
+Version 1.8.10
+(December 4th, 2012 from https://github.com/Elgg/Elgg/tree/1.8)
+
+ Contributing Developers:
+ * Krzysztof Różalski
+ * Lars Hærvig
+ * Paweł Sroka
+ * RiverVanRain
+ * Sem
+ * Steve Clay
+
+ Security Enhancements:
+ * Cached metadata respects access restrictions to fix problems with profile
+ field display.
+ * Group RSS feeds are restricted to valid entities
+
+ Enhancements:
+ * UX: Added a list of Administrators in the admin area
+ * UX: Limiting message board activity stream entries to excerpts
+ * Performance: Prefetching river entries
+ * Performance: Plugin entities are cached
+
+ Bugfixes:
+ * Removed superfluous commas in JS files to fix IE compatibility.
+ * API: Fixed Twitter API.
+ * Performance: Outputting valid ETags and expires headers.
+
+
+Version 1.8.9
+(November 11, 2012 from https://github.com/Elgg/Elgg/tree/1.8)
+
+ Contributing Developers:
+ * Brett Profitt
+ * Cash Costello
+ * Evan Winslow
+ * Jeroen Dalsem
+ * Jerome Bakker
+ * Matt Beckett
+ * Paweł Sroka
+ * Sem
+ * Steve Clay
+
+ Security Enhancements:
+ * Sample CLI installer cannot break site
+ * Removed XSS vulnerabilities in titles and user profiles
+
+ Enhancements:
+ * UX: A group's owner can transfer ownership to another member
+ * UX: Search queries persist in the search box
+ * Several (X)HTML validation improvements
+ * Improved performance via more aggressive entity and metadata caching
+ * BC: 1.7 group profile URLs forward correctly
+
+ Bugfixes:
+ * UX: Titles containing HTML tokens are never mangled
+ * UX: Empty user profile values saved properly
+ * UX: Blog creator always mentioned in activity stream (not user who published it)
+ * UI: Fixed ordering of registered menu items in some cases
+ * UI: Embed dialog does not break file inputs
+ * UI: Datepicker now respects language
+ * UI: More reliable display of access input in widgets
+ * UI: Group edit form is sticky
+ * UI: Site categories are sticky in forms
+ * API: Language fallback works in Javascript
+ * API: Fallback to default viewtype if invalid one given
+ * API: Notices reported for missing language keys
+ * Memcache now safe to use; never bypasses access control
+ * BC: upgrade shows comments consistently in activity stream
+
+
Version 1.8.8
(July 11, 2012 from https://github.com/Elgg/Elgg/tree/1.8)
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 0163757e7..a8e74d3a4 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -1,6 +1,7 @@
The following have made notable contributions to the Elgg Project.
(List in alphabetical order.)
+Steve Clay - http://www.mrclay.org/, https://twitter.com/mrclay_org
Cash Costello - cash@elgg.org, http://cashcostello.com/
@@ -20,10 +21,10 @@ Tom Read - MITRE http://mitre.org/
Justin Richer - MITRE http://mitre.org/
-Dave Tosh - davidgtosh@gmail.com, http://twitter.com/davetosh
+Dave Tosh - davidgtosh@gmail.com, http://twitter.com/davetosh
Ben Werdmuller - http://benwerd.com/
-Nicholas Whitt - nick.whitt@gmail.com, http://twitter.com/nogoodnick
+Nicholas Whitt - nick.whitt@gmail.com, http://twitter.com/nogoodnick
Evan Winslow - evan@elgg.org, http://evanwinslow.com/
diff --git a/actions/profile/edit.php b/actions/profile/edit.php
index b6d73ff2d..89bf2bc0b 100644
--- a/actions/profile/edit.php
+++ b/actions/profile/edit.php
@@ -25,7 +25,7 @@ if (!is_array($accesslevel)) {
* wrapper for recursive array walk decoding
*/
function profile_array_decoder(&$v) {
- $v = html_entity_decode($v, ENT_COMPAT, 'UTF-8');
+ $v = _elgg_html_decode($v);
}
$profile_fields = elgg_get_config('profile_fields');
@@ -37,7 +37,7 @@ foreach ($profile_fields as $shortname => $valuetype) {
if (is_array($value)) {
array_walk_recursive($value, 'profile_array_decoder');
} else {
- $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');
+ $value = _elgg_html_decode($value);
}
// limit to reasonable sizes
diff --git a/actions/register.php b/actions/register.php
index f23d5b381..810ceaf27 100644
--- a/actions/register.php
+++ b/actions/register.php
@@ -30,8 +30,6 @@ if (elgg_get_config('allow_registration')) {
$guid = register_user($username, $password, $name, $email, false, $friend_guid, $invitecode);
if ($guid) {
- elgg_clear_sticky_form('register');
-
$new_user = get_entity($guid);
// allow plugins to respond to self registration
@@ -54,6 +52,7 @@ if (elgg_get_config('allow_registration')) {
throw new RegistrationException(elgg_echo('registerbad'));
}
+ elgg_clear_sticky_form('register');
system_message(elgg_echo("registerok", array(elgg_get_site_entity()->name)));
// if exception thrown, this probably means there is a validation
@@ -76,4 +75,4 @@ if (elgg_get_config('allow_registration')) {
register_error(elgg_echo('registerdisabled'));
}
-forward(REFERER); \ No newline at end of file
+forward(REFERER);
diff --git a/engine/classes/ElggAutoP.php b/engine/classes/ElggAutoP.php
new file mode 100644
index 000000000..89d77e583
--- /dev/null
+++ b/engine/classes/ElggAutoP.php
@@ -0,0 +1,309 @@
+<?php
+
+/**
+ * Create wrapper P and BR elements in HTML depending on newlines. Useful when
+ * users use newlines to signal line and paragraph breaks. In all cases output
+ * should be well-formed markup.
+ *
+ * In DIV elements, Ps are only added when there would be at
+ * least two of them.
+ */
+class ElggAutoP {
+
+ public $encoding = 'UTF-8';
+
+ /**
+ * @var DOMDocument
+ */
+ protected $_doc = null;
+
+ /**
+ * @var DOMXPath
+ */
+ protected $_xpath = null;
+
+ protected $_blocks = 'address article area aside blockquote caption col colgroup dd
+ details div dl dt fieldset figure figcaption footer form h1 h2 h3 h4 h5 h6 header
+ hr hgroup legend map math menu nav noscript p pre section select style summary
+ table tbody td tfoot th thead tr ul ol option li';
+
+ /**
+ * @var array
+ */
+ protected $_inlines = 'a abbr audio b button canvas caption cite code command datalist
+ del dfn em embed i iframe img input ins kbd keygen label map mark meter object
+ output progress q rp rt ruby s samp script select small source span strong style
+ sub sup textarea time var video wbr';
+
+ /**
+ * Descend into these elements to add Ps
+ *
+ * @var array
+ */
+ protected $_descendList = 'article aside blockquote body details div footer form
+ header section';
+
+ /**
+ * Add Ps inside these elements
+ *
+ * @var array
+ */
+ protected $_alterList = 'article aside blockquote body details div footer header
+ section';
+
+ protected $_unique = '';
+
+ public function __construct() {
+ $this->_blocks = preg_split('@\\s+@', $this->_blocks);
+ $this->_descendList = preg_split('@\\s+@', $this->_descendList);
+ $this->_alterList = preg_split('@\\s+@', $this->_alterList);
+ $this->_inlines = preg_split('@\\s+@', $this->_inlines);
+ $this->_unique = md5(__FILE__);
+ }
+
+ /**
+ * Intance of class for singleton pattern.
+ * @var ElggAutoP
+ */
+ private static $instance;
+
+ /**
+ * Singleton pattern.
+ * @return ElggAutoP
+ */
+ public static function getInstance() {
+ $className = __CLASS__;
+ if (!(self::$instance instanceof $className)) {
+ self::$instance = new $className();
+ }
+ return self::$instance;
+ }
+
+ /**
+ * Create wrapper P and BR elements in HTML depending on newlines. Useful when
+ * users use newlines to signal line and paragraph breaks. In all cases output
+ * should be well-formed markup.
+ *
+ * In DIV, LI, TD, and TH elements, Ps are only added when their would be at
+ * least two of them.
+ *
+ * @param string $html snippet
+ * @return string|false output or false if parse error occurred
+ */
+ public function process($html) {
+ // normalize whitespace
+ $html = str_replace(array("\r\n", "\r"), "\n", $html);
+
+ // allows preserving entities untouched
+ $html = str_replace('&', $this->_unique . 'AMP', $html);
+
+ $this->_doc = new DOMDocument();
+
+ // parse to DOM, suppressing loadHTML warnings
+ // http://www.php.net/manual/en/domdocument.loadhtml.php#95463
+ libxml_use_internal_errors(true);
+
+ if (!$this->_doc->loadHTML("<html><meta http-equiv='content-type' "
+ . "content='text/html; charset={$this->encoding}'><body>{$html}</body>"
+ . "</html>")) {
+ return false;
+ }
+
+ $this->_xpath = new DOMXPath($this->_doc);
+ // start processing recursively at the BODY element
+ $nodeList = $this->_xpath->query('//body[1]');
+ $this->_addParagraphs($nodeList->item(0));
+
+ // serialize back to HTML
+ $html = $this->_doc->saveHTML();
+
+ // split AUTOPs into multiples at /\n\n+/
+ $html = preg_replace('/(' . $this->_unique . 'NL){2,}/', '</autop><autop>', $html);
+ $html = str_replace(array($this->_unique . 'BR', $this->_unique . 'NL', '<br>'),
+ '<br />',
+ $html);
+ $html = str_replace('<br /></autop>', '</autop>', $html);
+
+ // re-parse so we can handle new AUTOP elements
+
+ if (!$this->_doc->loadHTML($html)) {
+ return false;
+ }
+ // must re-create XPath object after DOM load
+ $this->_xpath = new DOMXPath($this->_doc);
+
+ // strip AUTOPs that only have comments/whitespace
+ foreach ($this->_xpath->query('//autop') as $autop) {
+ $hasContent = false;
+ if (trim($autop->textContent) !== '') {
+ $hasContent = true;
+ } else {
+ foreach ($autop->childNodes as $node) {
+ if ($node->nodeType === XML_ELEMENT_NODE) {
+ $hasContent = true;
+ break;
+ }
+ }
+ }
+ if (!$hasContent) {
+ // strip w/ preg_replace later (faster than moving nodes out)
+ $autop->setAttribute("r", "1");
+ }
+ }
+
+ // remove a single AUTOP inside certain elements
+ foreach ($this->_xpath->query('//div') as $el) {
+ $autops = $this->_xpath->query('./autop', $el);
+ if ($autops->length === 1) {
+ // strip w/ preg_replace later (faster than moving nodes out)
+ $autops->item(0)->setAttribute("r", "1");
+ }
+ }
+
+ $html = $this->_doc->saveHTML();
+
+ // trim to the contents of BODY
+ $bodyStart = strpos($html, '<body>');
+ $bodyEnd = strpos($html, '</body>', $bodyStart + 6);
+ $html = substr($html, $bodyStart + 6, $bodyEnd - $bodyStart - 6);
+
+ // strip AUTOPs that should be removed
+ $html = preg_replace('@<autop r="1">(.*?)</autop>@', '\\1', $html);
+
+ // commit to converting AUTOPs to Ps
+ $html = str_replace('<autop>', "\n<p>", $html);
+ $html = str_replace('</autop>', "</p>\n", $html);
+
+ $html = str_replace('<br>', '<br />', $html);
+ $html = str_replace($this->_unique . 'AMP', '&', $html);
+ return $html;
+ }
+
+ /**
+ * Add P and BR elements as necessary
+ *
+ * @param DOMElement $el
+ */
+ protected function _addParagraphs(DOMElement $el) {
+ // no need to recurse, just queue up
+ $elsToProcess = array($el);
+ $inlinesToProcess = array();
+ while ($el = array_shift($elsToProcess)) {
+ // if true, we can alter all child nodes, if not, we'll just call
+ // _addParagraphs on each element in the descendInto list
+ $alterInline = in_array($el->nodeName, $this->_alterList);
+
+ // inside affected elements, we want to trim leading whitespace from
+ // the first text node
+ $ltrimFirstTextNode = true;
+
+ // should we open a new AUTOP element to move inline elements into?
+ $openP = true;
+ $autop = null;
+
+ // after BR, ignore a newline
+ $isFollowingBr = false;
+
+ $node = $el->firstChild;
+ while (null !== $node) {
+ if ($alterInline) {
+ if ($openP) {
+ $openP = false;
+ // create a P to move inline content into (this may be removed later)
+ $autop = $el->insertBefore($this->_doc->createElement('autop'), $node);
+ }
+ }
+
+ $isElement = ($node->nodeType === XML_ELEMENT_NODE);
+ if ($isElement) {
+ $elName = $node->nodeName;
+ }
+ $isBlock = ($isElement && in_array($elName, $this->_blocks));
+
+ if ($alterInline) {
+ $isInline = $isElement && ! $isBlock;
+ $isText = ($node->nodeType === XML_TEXT_NODE);
+ $isLastInline = (! $node->nextSibling
+ || ($node->nextSibling->nodeType === XML_ELEMENT_NODE
+ && in_array($node->nextSibling->nodeName, $this->_blocks)));
+ if ($isElement) {
+ $isFollowingBr = ($node->nodeName === 'br');
+ }
+
+ if ($isText) {
+ $nodeText = $node->nodeValue;
+ if ($ltrimFirstTextNode) {
+ $nodeText = ltrim($nodeText);
+ $ltrimFirstTextNode = false;
+ }
+ if ($isFollowingBr && preg_match('@^[ \\t]*\\n[ \\t]*@', $nodeText, $m)) {
+ // if a user ends a line with <br>, don't add a second BR
+ $nodeText = substr($nodeText, strlen($m[0]));
+ }
+ if ($isLastInline) {
+ $nodeText = rtrim($nodeText);
+ }
+ $nodeText = str_replace("\n", $this->_unique . 'NL', $nodeText);
+ $tmpNode = $node;
+ $node = $node->nextSibling; // move loop to next node
+
+ // alter node in place, then move into AUTOP
+ $tmpNode->nodeValue = $nodeText;
+ $autop->appendChild($tmpNode);
+
+ continue;
+ }
+ }
+ if ($isBlock || ! $node->nextSibling) {
+ if ($isBlock) {
+ if (in_array($node->nodeName, $this->_descendList)) {
+ $elsToProcess[] = $node;
+ //$this->_addParagraphs($node);
+ }
+ }
+ $openP = true;
+ $ltrimFirstTextNode = true;
+ }
+ if ($alterInline) {
+ if (! $isBlock) {
+ $tmpNode = $node;
+ if ($isElement && false !== strpos($tmpNode->textContent, "\n")) {
+ $inlinesToProcess[] = $tmpNode;
+ }
+ $node = $node->nextSibling;
+ $autop->appendChild($tmpNode);
+ continue;
+ }
+ }
+
+ $node = $node->nextSibling;
+ }
+ }
+
+ // handle inline nodes
+ // no need to recurse, just queue up
+ while ($el = array_shift($inlinesToProcess)) {
+ $ignoreLeadingNewline = false;
+ foreach ($el->childNodes as $node) {
+ if ($node->nodeType === XML_ELEMENT_NODE) {
+ if ($node->nodeValue === 'BR') {
+ $ignoreLeadingNewline = true;
+ } else {
+ $ignoreLeadingNewline = false;
+ if (false !== strpos($node->textContent, "\n")) {
+ $inlinesToProcess[] = $node;
+ }
+ }
+ continue;
+ } elseif ($node->nodeType === XML_TEXT_NODE) {
+ $text = $node->nodeValue;
+ if ($text[0] === "\n" && $ignoreLeadingNewline) {
+ $text = substr($text, 1);
+ $ignoreLeadingNewline = false;
+ }
+ $node->nodeValue = str_replace("\n", $this->_unique . 'BR', $text);
+ }
+ }
+ }
+ }
+}
diff --git a/engine/classes/ElggPAM.php b/engine/classes/ElggPAM.php
index 0681a909b..f07095fc1 100644
--- a/engine/classes/ElggPAM.php
+++ b/engine/classes/ElggPAM.php
@@ -53,11 +53,17 @@ class ElggPAM {
foreach ($_PAM_HANDLERS[$this->policy] as $k => $v) {
$handler = $v->handler;
+ if (!is_callable($handler)) {
+ continue;
+ }
+ /* @var callable $handler */
+
$importance = $v->importance;
try {
// Execute the handler
- $result = $handler($credentials);
+ // @todo don't assume $handler is a global function
+ $result = call_user_func($handler, $credentials);
if ($result) {
$authenticated = true;
} elseif ($result === false) {
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
index 3e43c8e81..c6ce2905f 100644
--- a/engine/classes/ElggPlugin.php
+++ b/engine/classes/ElggPlugin.php
@@ -36,8 +36,9 @@ class ElggPlugin extends ElggObject {
* @warning Unlike other ElggEntity objects, you cannot null instantiate
* ElggPlugin. You must point it to an actual plugin GUID or location.
*
- * @param mixed $plugin The GUID of the ElggPlugin object or the path of
- * the plugin to load.
+ * @param mixed $plugin The GUID of the ElggPlugin object or the path of the plugin to load.
+ *
+ * @throws PluginException
*/
public function __construct($plugin) {
if (!$plugin) {
@@ -76,6 +77,8 @@ class ElggPlugin extends ElggObject {
// load the rest of the plugin
parent::__construct($existing_guid);
}
+
+ _elgg_cache_plugin_by_id($this);
}
/**
diff --git a/engine/classes/ElggPluginManifest.php b/engine/classes/ElggPluginManifest.php
index a4f5bb95d..6912c2b08 100644
--- a/engine/classes/ElggPluginManifest.php
+++ b/engine/classes/ElggPluginManifest.php
@@ -130,7 +130,7 @@ class ElggPluginManifest {
}
// see if we need to construct the xml object.
- if ($manifest instanceof XmlElement) {
+ if ($manifest instanceof ElggXMLElement) {
$manifest_obj = $manifest;
} else {
if (substr(trim($manifest), 0, 1) == '<') {
diff --git a/engine/classes/ElggPluginManifestParser.php b/engine/classes/ElggPluginManifestParser.php
index b0480d4d8..af152b561 100644
--- a/engine/classes/ElggPluginManifestParser.php
+++ b/engine/classes/ElggPluginManifestParser.php
@@ -53,10 +53,10 @@ abstract class ElggPluginManifestParser {
/**
* Loads the manifest XML to be parsed.
*
- * @param XmlElement $xml The Manifest XML object to be parsed
- * @param object $caller The object calling this parser.
+ * @param ElggXmlElement $xml The Manifest XML object to be parsed
+ * @param object $caller The object calling this parser.
*/
- public function __construct(XmlElement $xml, $caller) {
+ public function __construct(ElggXMLElement $xml, $caller) {
$this->manifestObject = $xml;
$this->caller = $caller;
}
diff --git a/engine/classes/ElggVolatileMetadataCache.php b/engine/classes/ElggVolatileMetadataCache.php
index 24ae58d42..8a33c198d 100644
--- a/engine/classes/ElggVolatileMetadataCache.php
+++ b/engine/classes/ElggVolatileMetadataCache.php
@@ -279,6 +279,9 @@ class ElggVolatileMetadataCache {
),
'selects' => array('n.string AS name', 'v.string AS value'),
'order_by' => 'n_table.entity_guid, n_table.time_created ASC',
+
+ // @todo don't know why this is necessary
+ 'wheres' => array(get_access_sql_suffix('n_table')),
);
$data = elgg_get_metadata($options);
diff --git a/engine/classes/ElggXMLElement.php b/engine/classes/ElggXMLElement.php
new file mode 100644
index 000000000..65a13912c
--- /dev/null
+++ b/engine/classes/ElggXMLElement.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * A parser for XML that uses SimpleXMLElement
+ *
+ * @package Elgg.Core
+ * @subpackage XML
+ */
+class ElggXMLElement {
+ /**
+ * @var SimpleXMLElement
+ */
+ private $_element;
+
+ /**
+ * Creates an ElggXMLParser from a string or existing SimpleXMLElement
+ *
+ * @param string|SimpleXMLElement $xml The XML to parse
+ */
+ public function __construct($xml) {
+ if ($xml instanceof SimpleXMLElement) {
+ $this->_element = $xml;
+ } else {
+ $this->_element = new SimpleXMLElement($xml);
+ }
+ }
+
+ /**
+ * @return string The name of the element
+ */
+ public function getName() {
+ return $this->_element->getName();
+ }
+
+ /**
+ * @return array:string The attributes
+ */
+ public function getAttributes() {
+ //include namespace declarations as attributes
+ $xmlnsRaw = $this->_element->getNamespaces();
+ $xmlns = array();
+ foreach ($xmlnsRaw as $key => $val) {
+ $label = 'xmlns' . ($key ? ":$key" : $key);
+ $xmlns[$label] = $val;
+ }
+ //get attributes and merge with namespaces
+ $attrRaw = $this->_element->attributes();
+ $attr = array();
+ foreach ($attrRaw as $key => $val) {
+ $attr[$key] = $val;
+ }
+ $attr = array_merge((array) $xmlns, (array) $attr);
+ $result = array();
+ foreach ($attr as $key => $val) {
+ $result[$key] = (string) $val;
+ }
+ return $result;
+ }
+
+ /**
+ * @return string CData
+ */
+ public function getContent() {
+ return (string) $this->_element;
+ }
+
+ /**
+ * @return array:ElggXMLElement Child elements
+ */
+ public function getChildren() {
+ $children = $this->_element->children();
+ $result = array();
+ foreach ($children as $val) {
+ $result[] = new ElggXMLElement($val);
+ }
+
+ return $result;
+ }
+
+ function __get($name) {
+ switch ($name) {
+ case 'name':
+ return $this->getName();
+ break;
+ case 'attributes':
+ return $this->getAttributes();
+ break;
+ case 'content':
+ return $this->getContent();
+ break;
+ case 'children':
+ return $this->getChildren();
+ break;
+ }
+ return null;
+ }
+
+ function __isset($name) {
+ switch ($name) {
+ case 'name':
+ return $this->getName() !== null;
+ break;
+ case 'attributes':
+ return $this->getAttributes() !== null;
+ break;
+ case 'content':
+ return $this->getContent() !== null;
+ break;
+ case 'children':
+ return $this->getChildren() !== null;
+ break;
+ }
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/engine/handlers/cache_handler.php b/engine/handlers/cache_handler.php
index b332ec379..7706c2c92 100644
--- a/engine/handlers/cache_handler.php
+++ b/engine/handlers/cache_handler.php
@@ -64,7 +64,7 @@ $ts = $matches[4];
// If is the same ETag, content didn't changed.
$etag = $ts;
-if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
+if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == "\"$etag\"") {
header("HTTP/1.1 304 Not Modified");
exit;
}
@@ -80,10 +80,10 @@ switch ($type) {
break;
}
-header('Expires: ' . date('r', strtotime("+6 months")), true);
+header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
header("Pragma: public", true);
header("Cache-Control: public", true);
-header("ETag: $etag");
+header("ETag: \"$etag\"");
$filename = $dataroot . 'views_simplecache/' . md5($viewtype . $view);
diff --git a/engine/lib/access.php b/engine/lib/access.php
index e8b3b0d52..3b2b7aeaa 100644
--- a/engine/lib/access.php
+++ b/engine/lib/access.php
@@ -88,11 +88,7 @@ function get_access_array($user_id = 0, $site_id = 0, $flush = false) {
// @todo everything from the db is cached.
// this cache might be redundant. But db cache is flushed on every db write.
- static $access_array;
-
- if (!isset($access_array)) {
- $access_array = array();
- }
+ static $access_array = array();
if ($user_id == 0) {
$user_id = elgg_get_logged_in_user_guid();
@@ -476,7 +472,7 @@ function can_edit_access_collection($collection_id, $user_guid = null) {
return false;
}
- $write_access = get_write_access_array($user->getGUID(), null, true);
+ $write_access = get_write_access_array($user->getGUID(), 0, true);
// don't ignore access when checking users.
if ($user_guid) {
@@ -560,8 +556,6 @@ function create_access_collection($name, $owner_guid = 0, $site_guid = 0) {
* @see remove_user_from_access_collection()
*/
function update_access_collection($collection_id, $members) {
- global $CONFIG;
-
$acl = get_access_collection($collection_id);
if (!$acl) {
@@ -1018,6 +1012,7 @@ function elgg_override_permissions($hook, $type, $value, $params) {
*/
function access_test($hook, $type, $value, $params) {
global $CONFIG;
+
$value[] = $CONFIG->path . 'engine/tests/api/access_collections.php';
return $value;
}
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index b65d98c95..3f23f079c 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -268,8 +268,9 @@ function admin_init() {
// users
elgg_register_admin_menu_item('administer', 'users', null, 20);
elgg_register_admin_menu_item('administer', 'online', 'users', 10);
- elgg_register_admin_menu_item('administer', 'newest', 'users', 20);
- elgg_register_admin_menu_item('administer', 'add', 'users', 30);
+ elgg_register_admin_menu_item('administer', 'admins', 'users', 20);
+ elgg_register_admin_menu_item('administer', 'newest', 'users', 30);
+ elgg_register_admin_menu_item('administer', 'add', 'users', 40);
// configure
// plugins
diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php
index 305aa00b6..b10e51130 100644
--- a/engine/lib/configuration.php
+++ b/engine/lib/configuration.php
@@ -91,23 +91,29 @@ function elgg_get_config($name, $site_guid = 0) {
return $CONFIG->$name;
}
- if ($site_guid === NULL) {
+ if ($site_guid === null) {
// installation wide setting
$value = datalist_get($name);
} else {
- // site specific setting
- if ($site_guid == 0) {
- $site_guid = (int) $CONFIG->site_id;
+ // hit DB only if we're not sure if value exists or not
+ if (!isset($CONFIG->site_config_loaded)) {
+ // site specific setting
+ if ($site_guid == 0) {
+ $site_guid = (int) $CONFIG->site_id;
+ }
+ $value = get_config($name, $site_guid);
+ } else {
+ $value = null;
}
- $value = get_config($name, $site_guid);
}
- if ($value !== false) {
- $CONFIG->$name = $value;
- return $value;
+ // @todo document why we don't cache false
+ if ($value === false) {
+ return null;
}
- return null;
+ $CONFIG->$name = $value;
+ return $value;
}
/**
@@ -558,6 +564,8 @@ function _elgg_load_site_config() {
$CONFIG->url = $CONFIG->wwwroot;
get_all_config();
+ // gives hint to elgg_get_config function how to approach missing values
+ $CONFIG->site_config_loaded = true;
}
/**
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index 26c1cccfd..540605876 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -671,7 +671,7 @@ function elgg_register_event_handler($event, $object_type, $callback, $priority
global $CONFIG;
if (empty($event) || empty($object_type)) {
- return FALSE;
+ return false;
}
if (!isset($CONFIG->events)) {
@@ -684,8 +684,8 @@ function elgg_register_event_handler($event, $object_type, $callback, $priority
$CONFIG->events[$event][$object_type] = array();
}
- if (!is_callable($callback)) {
- return FALSE;
+ if (!is_callable($callback, true)) {
+ return false;
}
$priority = max((int) $priority, 0);
@@ -695,7 +695,7 @@ function elgg_register_event_handler($event, $object_type, $callback, $priority
}
$CONFIG->events[$event][$object_type][$priority] = $callback;
ksort($CONFIG->events[$event][$object_type]);
- return TRUE;
+ return true;
}
/**
@@ -710,9 +710,12 @@ function elgg_register_event_handler($event, $object_type, $callback, $priority
*/
function elgg_unregister_event_handler($event, $object_type, $callback) {
global $CONFIG;
- foreach ($CONFIG->events[$event][$object_type] as $key => $event_callback) {
- if ($event_callback == $callback) {
- unset($CONFIG->events[$event][$object_type][$key]);
+
+ if (isset($CONFIG->events[$event]) && isset($CONFIG->events[$event][$object_type])) {
+ foreach ($CONFIG->events[$event][$object_type] as $key => $event_callback) {
+ if ($event_callback == $callback) {
+ unset($CONFIG->events[$event][$object_type][$key]);
+ }
}
}
}
@@ -770,14 +773,14 @@ function elgg_trigger_event($event, $object_type, $object = null) {
foreach ($events as $callback_list) {
if (is_array($callback_list)) {
foreach ($callback_list as $callback) {
- if (call_user_func_array($callback, $args) === FALSE) {
- return FALSE;
+ if (is_callable($callback) && (call_user_func_array($callback, $args) === false)) {
+ return false;
}
}
}
}
- return TRUE;
+ return true;
}
/**
@@ -850,7 +853,7 @@ function elgg_register_plugin_hook_handler($hook, $type, $callback, $priority =
global $CONFIG;
if (empty($hook) || empty($type)) {
- return FALSE;
+ return false;
}
if (!isset($CONFIG->hooks)) {
@@ -863,8 +866,8 @@ function elgg_register_plugin_hook_handler($hook, $type, $callback, $priority =
$CONFIG->hooks[$hook][$type] = array();
}
- if (!is_callable($callback)) {
- return FALSE;
+ if (!is_callable($callback, true)) {
+ return false;
}
$priority = max((int) $priority, 0);
@@ -874,7 +877,7 @@ function elgg_register_plugin_hook_handler($hook, $type, $callback, $priority =
}
$CONFIG->hooks[$hook][$type][$priority] = $callback;
ksort($CONFIG->hooks[$hook][$type]);
- return TRUE;
+ return true;
}
/**
@@ -889,9 +892,12 @@ function elgg_register_plugin_hook_handler($hook, $type, $callback, $priority =
*/
function elgg_unregister_plugin_hook_handler($hook, $entity_type, $callback) {
global $CONFIG;
- foreach ($CONFIG->hooks[$hook][$entity_type] as $key => $hook_callback) {
- if ($hook_callback == $callback) {
- unset($CONFIG->hooks[$hook][$entity_type][$key]);
+
+ if (isset($CONFIG->hooks[$hook]) && isset($CONFIG->hooks[$hook][$entity_type])) {
+ foreach ($CONFIG->hooks[$hook][$entity_type] as $key => $hook_callback) {
+ if ($hook_callback == $callback) {
+ unset($CONFIG->hooks[$hook][$entity_type][$key]);
+ }
}
}
}
@@ -970,10 +976,12 @@ function elgg_trigger_plugin_hook($hook, $type, $params = null, $returnvalue = n
foreach ($hooks as $callback_list) {
if (is_array($callback_list)) {
foreach ($callback_list as $hookcallback) {
- $args = array($hook, $type, $returnvalue, $params);
- $temp_return_value = call_user_func_array($hookcallback, $args);
- if (!is_null($temp_return_value)) {
- $returnvalue = $temp_return_value;
+ if (is_callable($hookcallback)) {
+ $args = array($hook, $type, $returnvalue, $params);
+ $temp_return_value = call_user_func_array($hookcallback, $args);
+ if (!is_null($temp_return_value)) {
+ $returnvalue = $temp_return_value;
+ }
}
}
}
@@ -1071,8 +1079,8 @@ function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
case E_USER_WARNING :
case E_RECOVERABLE_ERROR: // (e.g. type hint violation)
- // check if the error wasn't suppressed by @-functionname
- if(error_reporting()){
+ // check if the error wasn't suppressed by the error control operator (@)
+ if (error_reporting()) {
error_log("PHP WARNING: $error");
}
break;
@@ -1883,7 +1891,7 @@ function elgg_cacheable_view_page_handler($page, $type) {
header("Content-type: $content_type");
// @todo should js be cached when simple cache turned off
- //header('Expires: ' . date('r', time() + 864000));
+ //header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+10 days")), true);
//header("Pragma: public");
//header("Cache-Control: public");
//header("Content-Length: " . strlen($return));
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index a50567d9f..fda554388 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -17,13 +17,13 @@ global $ENTITY_CACHE;
$ENTITY_CACHE = array();
/**
- * Cache subtypes and related class names once loaded.
+ * Cache subtypes and related class names.
*
- * @global array $SUBTYPE_CACHE
+ * @global array|null $SUBTYPE_CACHE array once populated from DB, initially null
* @access private
*/
global $SUBTYPE_CACHE;
-$SUBTYPE_CACHE = NULL;
+$SUBTYPE_CACHE = null;
/**
* Invalidate this class's entry in the cache.
@@ -59,16 +59,24 @@ function invalidate_cache_for_entity($guid) {
function cache_entity(ElggEntity $entity) {
global $ENTITY_CACHE;
- // Don't cache entities while access control is off, otherwise they could be
+ // Don't cache non-plugin entities while access control is off, otherwise they could be
// exposed to users who shouldn't see them when control is re-enabled.
- if (elgg_get_ignore_access()) {
+ if (!($entity instanceof ElggPlugin) && elgg_get_ignore_access()) {
return;
}
// Don't store too many or we'll have memory problems
// TODO(evan): Pick a less arbitrary limit
if (count($ENTITY_CACHE) > 256) {
- unset($ENTITY_CACHE[array_rand($ENTITY_CACHE)]);
+ $random_guid = array_rand($ENTITY_CACHE);
+
+ unset($ENTITY_CACHE[$random_guid]);
+
+ // Purge separate metadata cache. Original idea was to do in entity destructor, but that would
+ // have caused a bunch of unnecessary purges at every shutdown. Doing it this way we have no way
+ // to know that the expunged entity will be GCed (might be another reference living), but that's
+ // OK; the metadata will reload if necessary.
+ elgg_get_metadata_cache()->clear($random_guid);
}
$ENTITY_CACHE[$entity->guid] = $entity;
@@ -87,8 +95,6 @@ function cache_entity(ElggEntity $entity) {
function retrieve_cached_entity($guid) {
global $ENTITY_CACHE;
- $guid = (int)$guid;
-
if (isset($ENTITY_CACHE[$guid])) {
if ($ENTITY_CACHE[$guid]->isFullyLoaded()) {
return $ENTITY_CACHE[$guid];
@@ -148,29 +154,23 @@ function retrieve_cached_entity_row($guid) {
* @access private
*/
function get_subtype_id($type, $subtype) {
- global $CONFIG, $SUBTYPE_CACHE;
+ global $SUBTYPE_CACHE;
- $type = sanitise_string($type);
- $subtype = sanitise_string($subtype);
-
- if ($subtype == "") {
- return FALSE;
+ if (!$subtype) {
+ return false;
}
- // @todo use the cache before hitting database
- $result = get_data_row("SELECT * from {$CONFIG->dbprefix}entity_subtypes
- where type='$type' and subtype='$subtype'");
-
- if ($result) {
- if (!$SUBTYPE_CACHE) {
- $SUBTYPE_CACHE = array();
- }
+ if ($SUBTYPE_CACHE === null) {
+ _elgg_populate_subtype_cache();
+ }
- $SUBTYPE_CACHE[$result->id] = $result;
+ // use the cache before hitting database
+ $result = _elgg_retrieve_cached_subtype($type, $subtype);
+ if ($result !== null) {
return $result->id;
}
- return FALSE;
+ return false;
}
/**
@@ -178,35 +178,67 @@ function get_subtype_id($type, $subtype) {
*
* @param int $subtype_id Subtype ID
*
- * @return string Subtype name
+ * @return string|false Subtype name, false if subtype not found
* @link http://docs.elgg.org/DataModel/Entities/Subtypes
* @see get_subtype_from_id()
* @access private
*/
function get_subtype_from_id($subtype_id) {
- global $CONFIG, $SUBTYPE_CACHE;
-
- $subtype_id = (int)$subtype_id;
+ global $SUBTYPE_CACHE;
if (!$subtype_id) {
return false;
}
+ if ($SUBTYPE_CACHE === null) {
+ _elgg_populate_subtype_cache();
+ }
+
if (isset($SUBTYPE_CACHE[$subtype_id])) {
return $SUBTYPE_CACHE[$subtype_id]->subtype;
}
- $result = get_data_row("SELECT * from {$CONFIG->dbprefix}entity_subtypes where id=$subtype_id");
- if ($result) {
- if (!$SUBTYPE_CACHE) {
- $SUBTYPE_CACHE = array();
- }
+ return false;
+}
+
+/**
+ * Retrieve subtype from the cache.
+ *
+ * @param string $type
+ * @param string $subtype
+ * @return stdClass|null
+ *
+ * @access private
+ */
+function _elgg_retrieve_cached_subtype($type, $subtype) {
+ global $SUBTYPE_CACHE;
- $SUBTYPE_CACHE[$subtype_id] = $result;
- return $result->subtype;
+ if ($SUBTYPE_CACHE === null) {
+ _elgg_populate_subtype_cache();
}
- return false;
+ foreach ($SUBTYPE_CACHE as $obj) {
+ if ($obj->type === $type && $obj->subtype === $subtype) {
+ return $obj;
+ }
+ }
+ return null;
+}
+
+/**
+ * Fetch all suptypes from DB to local cache.
+ *
+ * @access private
+ */
+function _elgg_populate_subtype_cache() {
+ global $CONFIG, $SUBTYPE_CACHE;
+
+ $results = get_data("SELECT * FROM {$CONFIG->dbprefix}entity_subtypes");
+
+ $SUBTYPE_CACHE = array();
+ foreach ($results as $row) {
+ $SUBTYPE_CACHE[$row->id] = $row;
+ }
}
/**
@@ -225,25 +257,19 @@ function get_subtype_from_id($subtype_id) {
* @access private
*/
function get_subtype_class($type, $subtype) {
- global $CONFIG, $SUBTYPE_CACHE;
-
- $type = sanitise_string($type);
- $subtype = sanitise_string($subtype);
-
- // @todo use the cache before going to the database
- $result = get_data_row("SELECT * from {$CONFIG->dbprefix}entity_subtypes
- where type='$type' and subtype='$subtype'");
+ global $SUBTYPE_CACHE;
- if ($result) {
- if (!$SUBTYPE_CACHE) {
- $SUBTYPE_CACHE = array();
- }
-
- $SUBTYPE_CACHE[$result->id] = $result;
- return $result->class;
+ if ($SUBTYPE_CACHE === null) {
+ _elgg_populate_subtype_cache();
+ }
+
+ // use the cache before going to the database
+ $obj = _elgg_retrieve_cached_subtype($type, $subtype);
+ if ($obj) {
+ return $obj->class;
}
- return NULL;
+ return null;
}
/**
@@ -257,29 +283,21 @@ function get_subtype_class($type, $subtype) {
* @access private
*/
function get_subtype_class_from_id($subtype_id) {
- global $CONFIG, $SUBTYPE_CACHE;
-
- $subtype_id = (int)$subtype_id;
+ global $SUBTYPE_CACHE;
if (!$subtype_id) {
- return false;
+ return null;
}
+ if ($SUBTYPE_CACHE === null) {
+ _elgg_populate_subtype_cache();
+ }
+
if (isset($SUBTYPE_CACHE[$subtype_id])) {
return $SUBTYPE_CACHE[$subtype_id]->class;
}
- $result = get_data_row("SELECT * from {$CONFIG->dbprefix}entity_subtypes where id=$subtype_id");
-
- if ($result) {
- if (!$SUBTYPE_CACHE) {
- $SUBTYPE_CACHE = array();
- }
- $SUBTYPE_CACHE[$subtype_id] = $result;
- return $result->class;
- }
-
- return NULL;
+ return null;
}
/**
@@ -305,21 +323,32 @@ function get_subtype_class_from_id($subtype_id) {
* @see get_entity()
*/
function add_subtype($type, $subtype, $class = "") {
- global $CONFIG;
- $type = sanitise_string($type);
- $subtype = sanitise_string($subtype);
- $class = sanitise_string($class);
+ global $CONFIG, $SUBTYPE_CACHE;
- // Short circuit if no subtype is given
- if ($subtype == "") {
+ if (!$subtype) {
return 0;
}
$id = get_subtype_id($type, $subtype);
- if ($id == 0) {
- return insert_data("insert into {$CONFIG->dbprefix}entity_subtypes"
- . " (type, subtype, class) values ('$type','$subtype','$class')");
+ if (!$id) {
+ // In cache we store non-SQL-escaped strings because that's what's returned by query
+ $cache_obj = (object) array(
+ 'type' => $type,
+ 'subtype' => $subtype,
+ 'class' => $class,
+ );
+
+ $type = sanitise_string($type);
+ $subtype = sanitise_string($subtype);
+ $class = sanitise_string($class);
+
+ $id = insert_data("INSERT INTO {$CONFIG->dbprefix}entity_subtypes"
+ . " (type, subtype, class) VALUES ('$type', '$subtype', '$class')");
+
+ // add entry to cache
+ $cache_obj->id = $id;
+ $SUBTYPE_CACHE[$id] = $cache_obj;
}
return $id;
@@ -361,22 +390,31 @@ function remove_subtype($type, $subtype) {
function update_subtype($type, $subtype, $class = '') {
global $CONFIG, $SUBTYPE_CACHE;
- if (!$id = get_subtype_id($type, $subtype)) {
- return FALSE;
+ $id = get_subtype_id($type, $subtype);
+ if (!$id) {
+ return false;
}
+
+ if ($SUBTYPE_CACHE === null) {
+ _elgg_populate_subtype_cache();
+ }
+
+ $unescaped_class = $class;
+
$type = sanitise_string($type);
$subtype = sanitise_string($subtype);
-
- $result = update_data("UPDATE {$CONFIG->dbprefix}entity_subtypes
+ $class = sanitise_string($class);
+
+ $success = 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;
+ if ($success && isset($SUBTYPE_CACHE[$id])) {
+ $SUBTYPE_CACHE[$id]->class = $unescaped_class;
}
- return $result;
+ return $success;
}
/**
@@ -1772,7 +1810,7 @@ function oddentity_to_elggentity(ODDEntity $element) {
if (!$tmp) {
// Construct new class with owner from session
$classname = get_subtype_class($class, $subclass);
- if ($classname != "") {
+ if ($classname) {
if (class_exists($classname)) {
$tmp = new $classname();
@@ -1838,7 +1876,7 @@ function oddentity_to_elggentity(ODDEntity $element) {
function import_entity_plugin_hook($hook, $entity_type, $returnvalue, $params) {
$element = $params['element'];
- $tmp = NULL;
+ $tmp = null;
if ($element instanceof ODDEntity) {
$tmp = oddentity_to_elggentity($element);
@@ -2011,7 +2049,7 @@ function get_entity_url($entity_guid) {
function elgg_register_entity_url_handler($entity_type, $entity_subtype, $function_name) {
global $CONFIG;
- if (!is_callable($function_name)) {
+ if (!is_callable($function_name, true)) {
return false;
}
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index 43421342c..538f601e1 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -136,14 +136,15 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
$functionname = "elgg_get_{$type}_from_id";
if (is_callable($functionname)) {
- $extender = $functionname($extender_id);
+ $extender = call_user_func($functionname, $extender_id);
} else {
return false;
}
- if (!is_a($extender, "ElggExtender")) {
+ if (!($extender instanceof ElggExtender)) {
return false;
}
+ /* @var ElggExtender $extender */
// If the owner is the specified user, great! They can edit.
if ($extender->getOwnerGUID() == $user->getGUID()) {
@@ -175,7 +176,7 @@ function elgg_register_extender_url_handler($extender_type, $extender_name, $fun
global $CONFIG;
- if (!is_callable($function_name)) {
+ if (!is_callable($function_name, true)) {
return false;
}
@@ -228,7 +229,7 @@ function get_extender_url(ElggExtender $extender) {
if ($url == "") {
$nameid = $extender->id;
if ($type == 'volatile') {
- $nameid == $extender->name;
+ $nameid = $extender->name;
}
$url = "export/$view/$guid/$type/$nameid/";
}
diff --git a/engine/lib/group.php b/engine/lib/group.php
index feb1f1e7f..852c08de9 100644
--- a/engine/lib/group.php
+++ b/engine/lib/group.php
@@ -33,6 +33,7 @@ function get_group_entity_as_row($guid) {
* @param string $description Description
*
* @return bool
+ * @access private
*/
function create_group_entity($guid, $name, $description) {
global $CONFIG;
diff --git a/engine/lib/notification.php b/engine/lib/notification.php
index 18faff27f..9e3c075a8 100644
--- a/engine/lib/notification.php
+++ b/engine/lib/notification.php
@@ -38,7 +38,7 @@ $NOTIFICATION_HANDLERS = array();
function register_notification_handler($method, $handler, $params = NULL) {
global $NOTIFICATION_HANDLERS;
- if (is_callable($handler)) {
+ if (is_callable($handler, true)) {
$NOTIFICATION_HANDLERS[$method] = new stdClass;
$NOTIFICATION_HANDLERS[$method]->handler = $handler;
@@ -131,8 +131,9 @@ function notify_user($to, $from, $subject, $message, array $params = NULL, $meth
// Extract method details from list
$details = $NOTIFICATION_HANDLERS[$method];
$handler = $details->handler;
+ /* @var callable $handler */
- if ((!$NOTIFICATION_HANDLERS[$method]) || (!$handler)) {
+ if ((!$NOTIFICATION_HANDLERS[$method]) || (!$handler) || (!is_callable($handler))) {
error_log(elgg_echo('NotificationException:NoHandlerFound', array($method)));
}
@@ -140,7 +141,7 @@ function notify_user($to, $from, $subject, $message, array $params = NULL, $meth
// Trigger handler and retrieve result.
try {
- $result[$guid][$method] = $handler(
+ $result[$guid][$method] = call_user_func($handler,
$from ? get_entity($from) : NULL, // From entity
get_entity($guid), // To entity
$subject, // The subject
diff --git a/engine/lib/objects.php b/engine/lib/objects.php
index f186c66cb..e5e8f67c4 100644
--- a/engine/lib/objects.php
+++ b/engine/lib/objects.php
@@ -31,6 +31,7 @@ function get_object_entity_as_row($guid) {
* @param string $description The object's description
*
* @return bool
+ * @access private
*/
function create_object_entity($guid, $title, $description) {
global $CONFIG;
diff --git a/engine/lib/output.php b/engine/lib/output.php
index 0069360f0..bff0bf6e9 100644
--- a/engine/lib/output.php
+++ b/engine/lib/output.php
@@ -16,7 +16,7 @@
**/
function parse_urls($text) {
// @todo this causes problems with <attr = "val">
- // must be ing <attr="val"> format (no space).
+ // must be in <attr="val"> format (no space).
// By default htmlawed rewrites tags to this format.
// if PHP supported conditional negative lookbehinds we could use this:
// $r = preg_replace_callback('/(?<!=)(?<![ ])?(?<!["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\),]+)/i',
@@ -43,51 +43,26 @@ function parse_urls($text) {
/**
* Create paragraphs from text with line spacing
- * Borrowed from Wordpress.
*
* @param string $pee The string
- * @param bool $br Add BRs?
+ * @deprecated Use elgg_autop instead
+ * @todo Add deprecation warning in 1.9
*
- * @todo Rewrite
* @return string
**/
-function autop($pee, $br = 1) {
- $pee = $pee . "\n"; // just to make things a little easier, pad the end
- $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
- // Space things out a little
- $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
- $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
- $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
- $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
- if (strpos($pee, '<object') !== false) {
- $pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
- $pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
- }
- $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
- $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
- $pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
- $pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
- $pee = preg_replace('|<p>|', "$1<p>", $pee);
- $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
- $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
- $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
- $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
- $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
- $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
- if ($br) {
- $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
- $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
- $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
- }
- $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
- $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
- //if (strpos($pee, '<pre') !== false) {
- // mind the space between the ? and >. Only there because of the comment.
- // $pee = preg_replace_callback('!(<pre.*? >)(.*?)</pre>!is', 'clean_pre', $pee );
- //}
- $pee = preg_replace("|\n</p>$|", '</p>', $pee);
-
- return $pee;
+function autop($pee) {
+ return elgg_autop($pee);
+}
+
+/**
+ * Create paragraphs from text with line spacing
+ *
+ * @param string $string The string
+ *
+ * @return string
+ **/
+function elgg_autop($string) {
+ return ElggAutoP::getInstance()->process($string);
}
/**
@@ -384,7 +359,7 @@ function elgg_get_friendly_time($time) {
/**
* Strip tags and offer plugins the chance.
* Plugins register for output:strip_tags plugin hook.
- * Original string included in $params['original_string']
+ * Original string included in $params['original_string']
*
* @param string $string Formatted string
*
@@ -398,3 +373,74 @@ function elgg_strip_tags($string) {
return $string;
}
+
+/**
+ * Apply html_entity_decode() to a string while re-entitising HTML
+ * special char entities to prevent them from being decoded back to their
+ * unsafe original forms.
+ *
+ * This relies on html_entity_decode() not translating entities when
+ * doing so leaves behind another entity, e.g. &amp;gt; if decoded would
+ * create &gt; which is another entity itself. This seems to escape the
+ * usual behaviour where any two paired entities creating a HTML tag are
+ * usually decoded, i.e. a lone &gt; is not decoded, but &lt;foo&gt; would
+ * be decoded to <foo> since it creates a full tag.
+ *
+ * Note: This function is poorly explained in the manual - which is really
+ * bad given its potential for misuse on user input already escaped elsewhere.
+ * Stackoverflow is littered with advice to use this function in the precise
+ * way that would lead to user input being capable of injecting arbitrary HTML.
+ *
+ * @param string $string
+ *
+ * @return string
+ *
+ * @author Pádraic Brady
+ * @copyright Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com)
+ * @license Released under dual-license GPL2/MIT by explicit permission of Pádraic Brady
+ *
+ * @access private
+ */
+function _elgg_html_decode($string) {
+ $string = str_replace(
+ array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'),
+ array('&amp;gt;', '&amp;lt;', '&amp;amp;', '&amp;quot;', '&amp;#039;'),
+ $string
+ );
+ $string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
+ $string = str_replace(
+ array('&amp;gt;', '&amp;lt;', '&amp;amp;', '&amp;quot;', '&amp;#039;'),
+ array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'),
+ $string
+ );
+ return $string;
+}
+
+/**
+ * Unit tests for Output
+ *
+ * @param sting $hook unit_test
+ * @param string $type system
+ * @param mixed $value Array of tests
+ * @param mixed $params Params
+ *
+ * @return array
+ * @access private
+ */
+function output_unit_test($hook, $type, $value, $params) {
+ global $CONFIG;
+ $value[] = $CONFIG->path . 'engine/tests/api/output.php';
+ return $value;
+}
+
+/**
+ * Initialise the Output subsystem.
+ *
+ * @return void
+ * @access private
+ */
+function output_init() {
+ elgg_register_plugin_hook_handler('unit_test', 'system', 'output_unit_test');
+}
+
+elgg_register_event_handler('init', 'system', 'output_init');
diff --git a/engine/lib/pagehandler.php b/engine/lib/pagehandler.php
index ba7518a77..0cf99b6fe 100644
--- a/engine/lib/pagehandler.php
+++ b/engine/lib/pagehandler.php
@@ -45,7 +45,10 @@ function page_handler($handler, $page) {
$page = $request['segments'];
$result = false;
- if (isset($CONFIG->pagehandler) && !empty($handler) && isset($CONFIG->pagehandler[$handler])) {
+ if (isset($CONFIG->pagehandler)
+ && !empty($handler)
+ && isset($CONFIG->pagehandler[$handler])
+ && is_callable($CONFIG->pagehandler[$handler])) {
$function = $CONFIG->pagehandler[$handler];
$result = call_user_func($function, $page, $handler);
}
@@ -76,14 +79,15 @@ function page_handler($handler, $page) {
* @param string $handler The page type to handle
* @param string $function Your function name
*
- * @return true|false Depending on success
+ * @return bool Depending on success
*/
function elgg_register_page_handler($handler, $function) {
global $CONFIG;
+
if (!isset($CONFIG->pagehandler)) {
$CONFIG->pagehandler = array();
}
- if (is_callable($function)) {
+ if (is_callable($function, true)) {
$CONFIG->pagehandler[$handler] = $function;
return true;
}
diff --git a/engine/lib/pam.php b/engine/lib/pam.php
index 4f9f44278..1c9c3bfe1 100644
--- a/engine/lib/pam.php
+++ b/engine/lib/pam.php
@@ -30,7 +30,9 @@ $_PAM_HANDLERS = array();
* failure, return false or throw an exception. Returning nothing indicates that
* the handler wants to be skipped.
*
- * @param string $handler The handler function in the format
+ * Note, $handler must be string callback (not an array/Closure).
+ *
+ * @param string $handler Callable global handler function in the format ()
* pam_handler($credentials = NULL);
* @param string $importance The importance - "sufficient" (default) or "required"
* @param string $policy The policy type, default is "user"
@@ -45,7 +47,8 @@ function register_pam_handler($handler, $importance = "sufficient", $policy = "u
$_PAM_HANDLERS[$policy] = array();
}
- if (is_callable($handler)) {
+ // @todo remove requirement that $handle be a global function
+ if (is_string($handler) && is_callable($handler, true)) {
$_PAM_HANDLERS[$policy][$handler] = new stdClass;
$_PAM_HANDLERS[$policy][$handler]->handler = $handler;
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index d5cd4fe76..ca4a957f4 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -176,6 +176,19 @@ function elgg_generate_plugin_entities() {
}
/**
+ * Cache a reference to this plugin by its ID
+ *
+ * @param ElggPlugin $plugin
+ *
+ * @access private
+ */
+function _elgg_cache_plugin_by_id(ElggPlugin $plugin) {
+ $map = (array) elgg_get_config('plugins_by_id_map');
+ $map[$plugin->getID()] = $plugin;
+ elgg_set_config('plugins_by_id_map', $map);
+}
+
+/**
* Returns an ElggPlugin object with the path $path.
*
* @param string $plugin_id The id (dir name) of the plugin. NOT the guid.
@@ -183,6 +196,11 @@ function elgg_generate_plugin_entities() {
* @since 1.8.0
*/
function elgg_get_plugin_from_id($plugin_id) {
+ $map = (array) elgg_get_config('plugins_by_id_map');
+ if (isset($map[$plugin_id])) {
+ return $map[$plugin_id];
+ }
+
$plugin_id = sanitize_string($plugin_id);
$db_prefix = get_config('dbprefix');
@@ -512,6 +530,8 @@ function elgg_namespace_plugin_private_setting($type, $name, $id = null) {
* @return string|false Plugin name, or false if no plugin name was called
* @since 1.8.0
* @access private
+ *
+ * @todo get rid of this
*/
function elgg_get_calling_plugin_id($mainfilename = false) {
if (!$mainfilename) {
@@ -920,6 +940,7 @@ function elgg_set_plugin_setting($name, $value, $plugin_id = null) {
*
* @return mixed
* @since 1.8.0
+ * @todo make $plugin_id required in future version
*/
function elgg_get_plugin_setting($name, $plugin_id = null) {
if ($plugin_id) {
diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php
index 09d541e22..01654b1ce 100644
--- a/engine/lib/relationships.php
+++ b/engine/lib/relationships.php
@@ -416,7 +416,7 @@ function elgg_list_entities_from_relationship_count($options) {
function elgg_register_relationship_url_handler($relationship_type, $function_name) {
global $CONFIG;
- if (!is_callable($function_name)) {
+ if (!is_callable($function_name, true)) {
return false;
}
diff --git a/engine/lib/river.php b/engine/lib/river.php
index b717a7756..33f34360e 100644
--- a/engine/lib/river.php
+++ b/engine/lib/river.php
@@ -361,6 +361,7 @@ function elgg_get_river(array $options = array()) {
}
$river_items = get_data($query, 'elgg_row_to_elgg_river_item');
+ _elgg_prefetch_river_entities($river_items);
return $river_items;
} else {
@@ -370,11 +371,56 @@ function elgg_get_river(array $options = array()) {
}
/**
+ * Prefetch entities that will be displayed in the river.
+ *
+ * @param ElggRiverItem[] $river_items
+ * @access private
+ */
+function _elgg_prefetch_river_entities(array $river_items) {
+ // prefetch objects and subjects
+ $guids = array();
+ foreach ($river_items as $item) {
+ if ($item->subject_guid && !retrieve_cached_entity($item->subject_guid)) {
+ $guids[$item->subject_guid] = true;
+ }
+ if ($item->object_guid && !retrieve_cached_entity($item->object_guid)) {
+ $guids[$item->object_guid] = true;
+ }
+ }
+ if ($guids) {
+ // avoid creating oversized query
+ // @todo how to better handle this?
+ $guids = array_slice($guids, 0, 300, true);
+ // return value unneeded, just priming cache
+ elgg_get_entities(array(
+ 'guids' => array_keys($guids),
+ 'limit' => 0,
+ ));
+ }
+
+ // prefetch object containers
+ $guids = array();
+ foreach ($river_items as $item) {
+ $object = $item->getObjectEntity();
+ if ($object->container_guid && !retrieve_cached_entity($object->container_guid)) {
+ $guids[$object->container_guid] = true;
+ }
+ }
+ if ($guids) {
+ $guids = array_slice($guids, 0, 300, true);
+ elgg_get_entities(array(
+ 'guids' => array_keys($guids),
+ 'limit' => 0,
+ ));
+ }
+}
+
+/**
* List river items
*
* @param array $options Any options from elgg_get_river() plus:
* pagination => BOOL Display pagination links (true)
-
+ *
* @return string
* @since 1.8.0
*/
diff --git a/engine/lib/sites.php b/engine/lib/sites.php
index 8b772668d..d9eb2d25e 100644
--- a/engine/lib/sites.php
+++ b/engine/lib/sites.php
@@ -58,6 +58,7 @@ function get_site_entity_as_row($guid) {
* @param string $url URL of the site
*
* @return bool
+ * @access private
*/
function create_site_entity($guid, $name, $description, $url) {
global $CONFIG;
diff --git a/engine/lib/upgrades/2010052601.php b/engine/lib/upgrades/2010052601.php
index 5b477910f..a9cca6dc5 100644
--- a/engine/lib/upgrades/2010052601.php
+++ b/engine/lib/upgrades/2010052601.php
@@ -9,14 +9,14 @@ $params = array('type' => 'group',
$groups = elgg_get_entities($params);
if ($groups) {
foreach ($groups as $group) {
- $group->name = html_entity_decode($group->name, ENT_COMPAT, 'UTF-8');
- $group->description = html_entity_decode($group->description, ENT_COMPAT, 'UTF-8');
- $group->briefdescription = html_entity_decode($group->briefdescription, ENT_COMPAT, 'UTF-8');
- $group->website = html_entity_decode($group->website, ENT_COMPAT, 'UTF-8');
+ $group->name = _elgg_html_decode($group->name);
+ $group->description = _elgg_html_decode($group->description);
+ $group->briefdescription = _elgg_html_decode($group->briefdescription);
+ $group->website = _elgg_html_decode($group->website);
if ($group->interests) {
$tags = $group->interests;
- foreach ($tags as $index=>$tag) {
- $tags[$index] = html_entity_decode($tag, ENT_COMPAT, 'UTF-8');
+ foreach ($tags as $index => $tag) {
+ $tags[$index] = _elgg_html_decode($tag);
}
$group->interests = $tags;
}
diff --git a/engine/lib/users.php b/engine/lib/users.php
index 527eff3cd..95ef9d176 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -44,6 +44,7 @@ function get_user_entity_as_row($guid) {
* @param string $code A code
*
* @return bool
+ * @access private
*/
function create_user_entity($guid, $name, $username, $password, $salt, $email, $language, $code) {
global $CONFIG;
diff --git a/engine/lib/views.php b/engine/lib/views.php
index 6135026a7..69bceabf5 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -101,15 +101,15 @@ function elgg_get_viewtype() {
return $CURRENT_SYSTEM_VIEWTYPE;
}
- $viewtype = get_input('view', NULL);
- if ($viewtype) {
+ $viewtype = get_input('view', '', false);
+ if (is_string($viewtype) && $viewtype !== '') {
// only word characters allowed.
- if (!preg_match('[\W]', $viewtype)) {
+ if (!preg_match('/\W/', $viewtype)) {
return $viewtype;
}
}
- if (isset($CONFIG->view) && !empty($CONFIG->view)) {
+ if (!empty($CONFIG->view)) {
return $CONFIG->view;
}
@@ -258,8 +258,6 @@ function elgg_get_view_location($view, $viewtype = '') {
} else {
return $CONFIG->views->locations[$viewtype][$view];
}
-
- return false;
}
/**
@@ -329,7 +327,7 @@ function elgg_view_exists($view, $viewtype = '', $recurse = true) {
$location = $CONFIG->views->locations[$viewtype][$view];
}
- if (file_exists($location . "{$viewtype}/{$view}.php")) {
+ if (file_exists("{$location}{$viewtype}/{$view}.php")) {
return true;
}
@@ -378,7 +376,7 @@ function elgg_view_exists($view, $viewtype = '', $recurse = true) {
* @param boolean $bypass If set to true, elgg_view will bypass any specified
* alternative template handler; by default, it will
* hand off to this if requested (see set_template_handler)
- * @param boolean $debug If set to true, the viewer will complain if it can't find a view
+ * @param boolean $ignored This argument is ignored and will be removed eventually
* @param string $viewtype If set, forces the viewtype for the elgg_view call to be
* this value (default: standard detection)
*
@@ -386,18 +384,30 @@ function elgg_view_exists($view, $viewtype = '', $recurse = true) {
* @see set_template_handler()
* @example views/elgg_view.php
* @link http://docs.elgg.org/View
- * @todo $debug isn't used.
- * @todo $usercache is redundant.
*/
-function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $viewtype = '') {
+function elgg_view($view, $vars = array(), $bypass = false, $ignored = false, $viewtype = '') {
global $CONFIG;
- static $usercache;
-
- $view = (string)$view;
+ if (!is_string($view) || !is_string($viewtype)) {
+ elgg_log("View and Viewtype in views must be a strings: $view", 'NOTICE');
+ return '';
+ }
// basic checking for bad paths
if (strpos($view, '..') !== false) {
- return false;
+ return '';
+ }
+
+ if (!is_array($vars)) {
+ elgg_log("Vars in views must be an array: $view", 'ERROR');
+ $vars = array();
+ }
+
+ // Get the current viewtype
+ if ($viewtype === '') {
+ $viewtype = elgg_get_viewtype();
+ } elseif (preg_match('/\W/', $viewtype)) {
+ // Viewtypes can only be alphanumeric
+ return '';
}
$view_orig = $view;
@@ -408,19 +418,6 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
elgg_trigger_event('pagesetup', 'system');
}
- if (!is_array($usercache)) {
- $usercache = array();
- }
-
- if (!is_array($vars)) {
- elgg_log("Vars in views must be an array: $view", 'ERROR');
- $vars = array();
- }
-
- if (empty($vars)) {
- $vars = array();
- }
-
// @warning - plugin authors: do not expect user, config, and url to be
// set by elgg_view() in the future. Instead, use elgg_get_logged_in_user_entity(),
// elgg_get_config(), and elgg_get_site_url() in your views.
@@ -475,16 +472,6 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
}
}
- // Get the current viewtype
- if (empty($viewtype)) {
- $viewtype = elgg_get_viewtype();
- }
-
- // Viewtypes can only be alphanumeric
- if (preg_match('[\W]', $viewtype)) {
- return '';
- }
-
// Set up any extensions to the requested view
if (isset($CONFIG->views->extensions[$view])) {
$viewlist = $CONFIG->views->extensions[$view];
@@ -496,19 +483,21 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
ob_start();
foreach ($viewlist as $priority => $view) {
+
$view_location = elgg_get_view_location($view, $viewtype);
$view_file = "$view_location$viewtype/$view.php";
- $default_location = elgg_get_view_location($view, 'default');
- $default_view_file = "{$default_location}default/$view.php";
-
// try to include view
if (!file_exists($view_file) || !include($view_file)) {
// requested view does not exist
$error = "$viewtype/$view view does not exist.";
// attempt to load default view
- if ($viewtype != 'default' && elgg_does_viewtype_fallback($viewtype)) {
+ if ($viewtype !== 'default' && elgg_does_viewtype_fallback($viewtype)) {
+
+ $default_location = elgg_get_view_location($view, 'default');
+ $default_view_file = "{$default_location}default/$view.php";
+
if (file_exists($default_view_file) && include($default_view_file)) {
// default view found
$error .= " Using default/$view instead.";
@@ -533,7 +522,7 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
// backward compatibility with less granular hook will be gone in 2.0
$content_tmp = elgg_trigger_plugin_hook('display', 'view', $params, $content);
- if ($content_tmp != $content) {
+ if ($content_tmp !== $content) {
$content = $content_tmp;
elgg_deprecated_notice('The display:view plugin hook is deprecated by view:view_name', 1.8);
}
@@ -559,33 +548,32 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
* @param string $view_extension This view is added to $view
* @param int $priority The priority, from 0 to 1000,
* to add at (lowest numbers displayed first)
- * @param string $viewtype Not used
*
* @return void
* @since 1.7.0
* @link http://docs.elgg.org/Views/Extend
* @example views/extend.php
*/
-function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '') {
+function elgg_extend_view($view, $view_extension, $priority = 501) {
global $CONFIG;
if (!isset($CONFIG->views)) {
- $CONFIG->views = new stdClass;
- }
-
- if (!isset($CONFIG->views->extensions)) {
- $CONFIG->views->extensions = array();
- }
-
- if (!isset($CONFIG->views->extensions[$view])) {
- $CONFIG->views->extensions[$view][500] = "{$view}";
+ $CONFIG->views = (object) array(
+ 'extensions' => array(),
+ );
+ $CONFIG->views->extensions[$view][500] = (string)$view;
+ } else {
+ if (!isset($CONFIG->views->extensions[$view])) {
+ $CONFIG->views->extensions[$view][500] = (string)$view;
+ }
}
+ // raise priority until it doesn't match one already registered
while (isset($CONFIG->views->extensions[$view][$priority])) {
$priority++;
}
- $CONFIG->views->extensions[$view][$priority] = "{$view_extension}";
+ $CONFIG->views->extensions[$view][$priority] = (string)$view_extension;
ksort($CONFIG->views->extensions[$view]);
}
@@ -601,14 +589,6 @@ function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '
function elgg_unextend_view($view, $view_extension) {
global $CONFIG;
- if (!isset($CONFIG->views)) {
- return FALSE;
- }
-
- if (!isset($CONFIG->views->extensions)) {
- return FALSE;
- }
-
if (!isset($CONFIG->views->extensions[$view])) {
return FALSE;
}
@@ -1105,10 +1085,6 @@ function elgg_view_annotation_list($annotations, array $vars = array()) {
* @todo Change the hook name.
*/
function elgg_view_entity_annotations(ElggEntity $entity, $full_view = true) {
- if (!$entity) {
- return false;
- }
-
if (!($entity instanceof ElggEntity)) {
return false;
}
@@ -1131,7 +1107,7 @@ function elgg_view_entity_annotations(ElggEntity $entity, $full_view = true) {
* This is a shortcut for {@elgg_view page/elements/title}.
*
* @param string $title The page title
- * @param string $vars View variables (was submenu be displayed? (deprecated))
+ * @param array $vars View variables (was submenu be displayed? (deprecated))
*
* @return string The HTML (etc)
*/
@@ -1203,7 +1179,7 @@ function elgg_view_comments($entity, $add_comment = true, array $vars = array())
*
* @param string $image The icon and other information
* @param string $body Description content
- * @param string $vars Additional parameters for the view
+ * @param array $vars Additional parameters for the view
*
* @return string
* @since 1.8.0
@@ -1230,7 +1206,6 @@ function elgg_view_image_block($image, $body, $vars = array()) {
* @since 1.8.0
*/
function elgg_view_module($type, $title, $body, array $vars = array()) {
-
$vars['class'] = elgg_extract('class', $vars, '') . " elgg-module-$type";
$vars['title'] = $title;
$vars['body'] = $body;
@@ -1243,11 +1218,15 @@ function elgg_view_module($type, $title, $body, array $vars = array()) {
* @param ElggRiverItem $item A river item object
* @param array $vars An array of variables for the view
*
- * @return string|false Depending on success
+ * @return string returns empty string if could not be rendered
*/
function elgg_view_river_item($item, array $vars = array()) {
+ if (!($item instanceof ElggRiverItem)) {
+ return '';
+ }
// checking default viewtype since some viewtypes do not have unique views per item (rss)
- if (!$item || !$item->getView() || !elgg_view_exists($item->getView(), 'default')) {
+ $view = $item->getView();
+ if (!$view || !elgg_view_exists($view, 'default')) {
return '';
}
@@ -1339,7 +1318,7 @@ function elgg_view_list_item($item, array $vars = array()) {
return elgg_view_river_item($item, $vars);
}
- return false;
+ return '';
}
/**
@@ -1354,7 +1333,7 @@ function elgg_view_list_item($item, array $vars = array()) {
*/
function elgg_view_icon($name, $class = '') {
// @todo deprecate boolean in Elgg 1.9
- if (is_bool($class) && $class === true) {
+ if ($class === true) {
$class = 'float';
}
return "<span class=\"elgg-icon elgg-icon-$name $class\"></span>";
@@ -1403,7 +1382,8 @@ function elgg_view_access_collections($owner_guid) {
*/
function set_template_handler($function_name) {
global $CONFIG;
- if (!empty($function_name) && is_callable($function_name)) {
+
+ if (is_callable($function_name)) {
$CONFIG->template_handler = $function_name;
return true;
}
@@ -1516,17 +1496,13 @@ function elgg_view_tree($view_root, $viewtype = "") {
* @param string $base_location_path The base views directory to use with elgg_set_view_location()
* @param string $viewtype The type of view we're looking at (default, rss, etc)
*
- * @return void
+ * @return bool returns false if folder can't be read
* @since 1.7.0
* @see elgg_set_view_location()
* @todo This seems overly complicated.
* @access private
*/
function autoregister_views($view_base, $folder, $base_location_path, $viewtype) {
- if (!isset($i)) {
- $i = 0;
- }
-
if ($handle = opendir($folder)) {
while ($view = readdir($handle)) {
if (!in_array($view, array('.', '..', '.svn', 'CVS')) && !is_dir($folder . "/" . $view)) {
@@ -1608,16 +1584,15 @@ function elgg_views_handle_deprecated_views() {
function elgg_views_boot() {
global $CONFIG;
- elgg_register_simplecache_view('css/elgg');
elgg_register_simplecache_view('css/ie');
elgg_register_simplecache_view('css/ie6');
elgg_register_simplecache_view('css/ie7');
- elgg_register_simplecache_view('js/elgg');
elgg_register_js('jquery', '/vendors/jquery/jquery-1.6.4.min.js', 'head');
elgg_register_js('jquery-ui', '/vendors/jquery/jquery-ui-1.8.16.min.js', 'head');
elgg_register_js('jquery.form', '/vendors/jquery/jquery.form.js');
-
+
+ elgg_register_simplecache_view('js/elgg');
$elgg_js_url = elgg_get_simplecache_url('js', 'elgg');
elgg_register_js('elgg', $elgg_js_url, 'head');
@@ -1626,14 +1601,17 @@ function elgg_views_boot() {
elgg_load_js('elgg');
elgg_register_simplecache_view('js/lightbox');
- elgg_register_simplecache_view('css/lightbox');
$lightbox_js_url = elgg_get_simplecache_url('js', 'lightbox');
elgg_register_js('lightbox', $lightbox_js_url);
+
+ elgg_register_simplecache_view('css/lightbox');
$lightbox_css_url = elgg_get_simplecache_url('css', 'lightbox');
elgg_register_css('lightbox', $lightbox_css_url);
+ elgg_register_simplecache_view('css/elgg');
$elgg_css_url = elgg_get_simplecache_url('css', 'elgg');
elgg_register_css('elgg', $elgg_css_url);
+
elgg_load_css('elgg');
elgg_register_ajax_view('js/languages');
@@ -1647,7 +1625,7 @@ function elgg_views_boot() {
$views = scandir($view_path);
foreach ($views as $view) {
- if ('.' !== substr($view, 0, 1) && is_dir($view_path . $view)) {
+ if ($view[0] !== '.' && is_dir($view_path . $view)) {
elgg_register_viewtype($view);
}
}
diff --git a/engine/lib/web_services.php b/engine/lib/web_services.php
index da3ed76a9..c8e4a13cc 100644
--- a/engine/lib/web_services.php
+++ b/engine/lib/web_services.php
@@ -232,6 +232,7 @@ function execute_method($method) {
$function = $API_METHODS[$method]["function"];
$serialised_parameters = trim($serialised_parameters, ", ");
+ // @todo document why we cannot use call_user_func_array here
$result = eval("return $function($serialised_parameters);");
// Sanity check result
@@ -1194,6 +1195,8 @@ $ERRORS = array();
*
* @return void
* @access private
+ *
+ * @throws Exception
*/
function _php_api_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
global $ERRORS;
@@ -1278,11 +1281,9 @@ function service_handler($handler, $request) {
// no handlers set or bad url
header("HTTP/1.0 404 Not Found");
exit;
- } else if (isset($CONFIG->servicehandler[$handler])
- && is_callable($CONFIG->servicehandler[$handler])) {
-
+ } else if (isset($CONFIG->servicehandler[$handler]) && is_callable($CONFIG->servicehandler[$handler])) {
$function = $CONFIG->servicehandler[$handler];
- $function($request, $handler);
+ call_user_func($function, $request, $handler);
} else {
// no handler for this web service
header("HTTP/1.0 404 Not Found");
@@ -1301,10 +1302,11 @@ function service_handler($handler, $request) {
*/
function register_service_handler($handler, $function) {
global $CONFIG;
+
if (!isset($CONFIG->servicehandler)) {
$CONFIG->servicehandler = array();
}
- if (is_callable($function)) {
+ if (is_callable($function, true)) {
$CONFIG->servicehandler[$handler] = $function;
return true;
}
@@ -1319,11 +1321,13 @@ function register_service_handler($handler, $function) {
*
* @param string $handler web services type
*
- * @return 1.7.0
+ * @return void
+ * @since 1.7.0
*/
function unregister_service_handler($handler) {
global $CONFIG;
- if (isset($CONFIG->servicehandler) && isset($CONFIG->servicehandler[$handler])) {
+
+ if (isset($CONFIG->servicehandler, $CONFIG->servicehandler[$handler])) {
unset($CONFIG->servicehandler[$handler]);
}
}
@@ -1333,6 +1337,8 @@ function unregister_service_handler($handler) {
*
* @return void
* @access private
+ *
+ * @throws SecurityException|APIException
*/
function rest_handler() {
global $CONFIG;
@@ -1387,7 +1393,7 @@ function rest_handler() {
/**
* Unit tests for API
*
- * @param sting $hook unit_test
+ * @param string $hook unit_test
* @param string $type system
* @param mixed $value Array of tests
* @param mixed $params Params
@@ -1397,6 +1403,7 @@ function rest_handler() {
*/
function api_unit_test($hook, $type, $value, $params) {
global $CONFIG;
+
$value[] = $CONFIG->path . 'engine/tests/services/api.php';
return $value;
}
@@ -1418,15 +1425,18 @@ function api_init() {
elgg_echo("system.api.list"), "GET", false, false);
// The authentication token api
- expose_function("auth.gettoken",
- "auth_gettoken", array(
- 'username' => array ('type' => 'string'),
- 'password' => array ('type' => 'string'),
- ),
- elgg_echo('auth.gettoken'),
- 'POST',
- false,
- false);
+ expose_function(
+ "auth.gettoken",
+ "auth_gettoken",
+ array(
+ 'username' => array ('type' => 'string'),
+ 'password' => array ('type' => 'string'),
+ ),
+ elgg_echo('auth.gettoken'),
+ 'POST',
+ false,
+ false
+ );
}
diff --git a/engine/lib/xml.php b/engine/lib/xml.php
index 813bc4ee0..ff82d7e8a 100644
--- a/engine/lib/xml.php
+++ b/engine/lib/xml.php
@@ -101,47 +101,11 @@ function serialise_array_to_xml(array $data, $n = 0) {
/**
* Parse an XML file into an object.
- * Based on code from http://de.php.net/manual/en/function.xml-parse-into-struct.php by
- * efredricksen at gmail dot com
*
* @param string $xml The XML
*
* @return object
*/
function xml_to_object($xml) {
- $parser = xml_parser_create();
-
- // Parse $xml into a structure
- xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
- xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
- xml_parse_into_struct($parser, $xml, $tags);
-
- xml_parser_free($parser);
-
- $elements = array();
- $stack = array();
-
- foreach ($tags as $tag) {
- $index = count($elements);
-
- if ($tag['type'] == "complete" || $tag['type'] == "open") {
- $elements[$index] = new XmlElement;
- $elements[$index]->name = $tag['tag'];
- $elements[$index]->attributes = elgg_extract('attributes', $tag, '');
- $elements[$index]->content = elgg_extract('value', $tag, '');
-
- if ($tag['type'] == "open") {
- $elements[$index]->children = array();
- $stack[count($stack)] = &$elements;
- $elements = &$elements[$index]->children;
- }
- }
-
- if ($tag['type'] == "close") {
- $elements = &$stack[count($stack) - 1];
- unset($stack[count($stack) - 1]);
- }
- }
-
- return $elements[0];
+ return new ElggXMLElement($xml);
}
diff --git a/engine/tests/api/metadata.php b/engine/tests/api/metadata.php
index 9933263d1..825290d80 100644
--- a/engine/tests/api/metadata.php
+++ b/engine/tests/api/metadata.php
@@ -102,14 +102,14 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
$e = new ElggObject();
$e->save();
- for ($i=0; $i<30; $i++) {
- $name = "test_metadata" . rand(0, 10000);
+ for ($i = 0; $i < 30; $i++) {
+ $name = "test_metadata$i";
$e->$name = rand(0, 10000);
}
$options = array(
'guid' => $e->getGUID(),
- 'limit' => 0
+ 'limit' => 0,
);
$md = elgg_get_metadata($options);
diff --git a/engine/tests/api/output.php b/engine/tests/api/output.php
new file mode 100644
index 000000000..c3d5aa8c6
--- /dev/null
+++ b/engine/tests/api/output.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Test case for ElggAutoP functionality.
+ */
+class ElggCoreOutputAutoPTest extends ElggCoreUnitTest {
+
+ /**
+ * @var ElggAutoP
+ */
+ protected $_autop;
+
+ public function setUp() {
+ $this->_autop = new ElggAutoP();
+ }
+
+ public function testDomRoundtrip() {
+ $d = dir(dirname(dirname(__FILE__)) . '/test_files/output/autop');
+ $in = file_get_contents($d->path . "/domdoc_in.html");
+ $exp = file_get_contents($d->path . "/domdoc_exp.html");
+ $exp = $this->flattenString($exp);
+
+ $doc = new DOMDocument();
+ libxml_use_internal_errors(true);
+ $doc->loadHTML("<html><meta http-equiv='content-type' content='text/html; charset=utf-8'><body>"
+ . $in . '</body></html>');
+ $serialized = $doc->saveHTML();
+ list(,$out) = explode('<body>', $serialized, 2);
+ list($out) = explode('</body>', $out, 2);
+ $out = $this->flattenString($out);
+
+ $this->assertEqual($exp, $out, "DOMDocument's parsing/serialization roundtrip");
+ }
+
+ public function testProcess() {
+ $data = $this->provider();
+ foreach ($data as $row) {
+ list($test, $in, $exp) = $row;
+ $exp = $this->flattenString($exp);
+ $out = $this->_autop->process($in);
+ $out = $this->flattenString($out);
+
+ $this->assertEqual($exp, $out, "Equality case {$test}");
+ }
+ }
+
+ public function provider() {
+ $d = dir(dirname(dirname(__FILE__)) . '/test_files/output/autop');
+ $tests = array();
+ while (false !== ($entry = $d->read())) {
+ if (preg_match('/^([a-z\\-]+)\.in\.html$/i', $entry, $m)) {
+ $tests[] = $m[1];
+ }
+ }
+
+ $data = array();
+ foreach ($tests as $test) {
+ $data[] = array(
+ $test,
+ file_get_contents($d->path . '/' . "{$test}.in.html"),
+ file_get_contents($d->path . '/' . "{$test}.exp.html"),
+ );
+ }
+ return $data;
+ }
+
+ /**
+ * Different versions of PHP return different whitespace between tags.
+ * Removing all line breaks normalizes that.
+ */
+ public function flattenString($string) {
+ $r = preg_replace('/[\n\r]+/', '', $string);
+ return $r;
+ }
+} \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/block-a.exp.norun.html b/engine/tests/test_files/output/autop/block-a.exp.norun.html
new file mode 100644
index 000000000..addf29dec
--- /dev/null
+++ b/engine/tests/test_files/output/autop/block-a.exp.norun.html
@@ -0,0 +1,6 @@
+
+<p>HTML5 allows A to contain block-level content</p>
+<a href="foo"><h3>A treated as block</h3>
+<p>Read more</p>
+</a>
+<p><a href="foo">A treated as<br /> inline</a></p>
diff --git a/engine/tests/test_files/output/autop/block-a.in.norun.html b/engine/tests/test_files/output/autop/block-a.in.norun.html
new file mode 100644
index 000000000..fc2dac43a
--- /dev/null
+++ b/engine/tests/test_files/output/autop/block-a.in.norun.html
@@ -0,0 +1,9 @@
+HTML5 allows A to contain block-level content
+<a href="foo">
+
+ <h3>A treated as block</h3>
+
+ Read more
+</a>
+<a href="foo">A treated as
+ inline</a>
diff --git a/engine/tests/test_files/output/autop/domdoc_exp.html b/engine/tests/test_files/output/autop/domdoc_exp.html
new file mode 100644
index 000000000..8480c1083
--- /dev/null
+++ b/engine/tests/test_files/output/autop/domdoc_exp.html
@@ -0,0 +1,46 @@
+›
+Vietnamese - Tiếng Việt
+
+<h1>h1</h1>
+<p>Paragraph <a href="http://google.com/">link</a> <strong>Bold</strong> <em>italic</em> <em><strong>bolditalic</strong></em> <span style="background-color: #ffff00; "></span></p>
+<h2>h2</h2>
+<p>Paragraph <span style="font-size: xx-small;">size1</span> <span style="font-size: x-small;">size2</span> <span style="font-size: medium;">size4</span></p>
+<h3>h3</h3>
+<p>Paragraph <span style="text-decoration: underline;">underline</span> <span style="text-decoration: line-through;">strikethrough</span> <span style="color: #ff0000;">color</span> <span style="background-color: #ffff00; ">background</span></p>
+<blockquote>
+ <p>Blockquoted paragraph</p>
+</blockquote>
+<p>Paragraph following blockquote</p>
+<ul><li>Unordered</li>
+ <li>List</li>
+</ul><p>Paragraph between lists</p>
+<ol><li>Ordered</li>
+ <li>List</li>
+</ol><p>Paragraph between lists</p>
+<ul><li>OL list</li>
+ <li>nested<ol><li>inside a</li>
+ <li>UL list</li>
+ </ol></li>
+</ul><p>Paragraph between lists</p>
+<table border="0"><tbody><tr><td>Table with</td>
+ <td></td>
+ </tr><tr><td></td>
+ <td>border=0</td>
+ </tr></tbody></table><p>Paragraph</p>
+<ol><li>UL list</li>
+ <li>nested
+ <ul><li>inside a</li>
+ <li>OL list</li>
+ </ul></li>
+</ol><p>Paragraph between tables</p>
+<table border="1" cellpadding="5"><tbody><tr><td>Table with border=1</td>
+ <td></td>
+ </tr><tr><td></td>
+ <td>cellpadding = 5</td>
+ </tr></tbody></table><p>Paragraph between tables</p>
+<table border="2"><tbody><tr><td>Table with</td>
+ <td></td>
+ </tr><tr><td></td>
+ <td>border=2</td>
+ </tr></tbody></table> \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/domdoc_in.html b/engine/tests/test_files/output/autop/domdoc_in.html
new file mode 100644
index 000000000..4c465b435
--- /dev/null
+++ b/engine/tests/test_files/output/autop/domdoc_in.html
@@ -0,0 +1,80 @@
+&#8250;
+&nbsp;
+Vietnamese - Tiếng Việt
+
+<h1>h1</h1>
+<p>Paragraph <a href="http://google.com/">link</a> <strong>Bold</strong> <em>italic</em> <em><strong>bolditalic</strong></em>&nbsp;<span style="background-color: #ffff00; "></span></p>
+<h2>h2</h2>
+<p>Paragraph <span style="font-size: xx-small;">size1</span> <span style="font-size: x-small;">size2</span> <span style="font-size: medium;">size4</span></p>
+<h3>h3</h3>
+<p>Paragraph <span style="text-decoration: underline;">underline</span> <span style="text-decoration: line-through;">strikethrough</span> <span style="color: #ff0000;">color</span> <span style="background-color: #ffff00; ">background</span></p>
+<blockquote>
+ <p>Blockquoted paragraph</p>
+</blockquote>
+<p>Paragraph following blockquote</p>
+<ul>
+ <li>Unordered</li>
+ <li>List</li>
+</ul>
+<p>Paragraph between lists</p>
+<ol>
+ <li>Ordered</li>
+ <li>List</li>
+</ol>
+<p>Paragraph between lists</p>
+<ul>
+ <li>OL list</li>
+ <li>nested<ol>
+ <li>inside a</li>
+ <li>UL list</li>
+ </ol></li>
+</ul>
+<p>Paragraph between lists</p>
+<table border="0">
+ <tbody>
+ <tr>
+ <td>Table with</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>border=0</td>
+ </tr>
+ </tbody>
+</table>
+<p>Paragraph</p>
+<ol>
+ <li>UL list</li>
+ <li>nested
+ <ul>
+ <li>inside a</li>
+ <li>OL list</li>
+ </ul>
+ </li>
+</ol>
+<p>Paragraph between tables</p>
+<table border="1" cellpadding="5">
+ <tbody>
+ <tr>
+ <td>Table with border=1</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>cellpadding = 5</td>
+ </tr>
+ </tbody>
+</table>
+<p>Paragraph between tables</p>
+<table border="2">
+ <tbody>
+ <tr>
+ <td>Table with</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>border=2</td>
+ </tr>
+ </tbody>
+</table> \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/typical-post.exp.html b/engine/tests/test_files/output/autop/typical-post.exp.html
new file mode 100644
index 000000000..f9d75a114
--- /dev/null
+++ b/engine/tests/test_files/output/autop/typical-post.exp.html
@@ -0,0 +1,84 @@
+<h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h2>
+<p><img class="alignright size-thumbnail wp-image-905" title="Surest Things mixing session in Adobe Audition" src="http://www.mrclay.org/wp-content/uploads/2010/09/surestThings_audition-150x150.png" alt="screenshot of Audition mixing session" width="150" height="150">Vivamus enim ante, <em>mattis eget imperdiet nec, pharetra vel velit.</em> Sed at euismod nibh. Praesent lacus tellus, <a href="http://google.com/">posuere et convallis</a> a, <strong>mollis et tellus. Suspendisse potenti</strong>. Phasellus tincidunt dignissim est eget mattis. Vestibulum lacinia <del>condimentum tellus, non vestibulum erat dapibus</del> quis. Aliquam arcu nibh, viverra adipiscing eleifend quis, pretium vitae ipsum.</p>
+
+<p>Curabitur turpis ante, <span style="color: #993300;">congue ac dapibus quis, vehicula ac orci.</span> Nunc luctus neque non massa porta sed pharetra ante accumsan. <a href="http://google.com/">Nam suscipit</a> risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor.</p>
+<h3>Donec at massa ante, sagittis fermentum urna.</h3><blockquote>
+<p>Mauris volutpat est id massa volutpat lacinia. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In in nisl mauris. In aliquet pretium nisl, vel convallis neque cursus vitae. Curabitur id mauris in urna gravida ornare.</p>
+
+<p>[caption id="attachment_719" align="alignleft" width="150" caption="Ibanez AGB140 Bass"]<img class="size-thumbnail wp-image-719" title="Ibanez AGB140 Bass" src="http://www.mrclay.org/wp-content/uploads/2010/04/agb140-e1271773766573-150x150.jpg" alt="Ibanez AGB140 Bass" width="150" height="150">[/caption]</p>
+
+<p>Aenean <a href="http://google.com/">aliquet cursus purus sed gravida. Cras auctor euismod justo, ac dictum purus facilisis dignissim.</a> Quisque facilisis porta sem, ac suscipit quam molestie nec. Pellentesque quis hendrerit enim. Vivamus tempor erat diam. Sed eu felis nunc. Cras posuere lorem commodo turpis mollis sagittis. Mauris lobortis nunc felis.</p>
+
+<p>Maecenas elit lorem, varius sed condimentum ac, cursus et magna. Nam ut massa id augue consectetur porttitor eleifend in nunc. Curabitur cursus varius dictum. Vestibulum vel justo et neque tempus placerat a vel sapien.</p>
+</blockquote>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus enim ante, mattis eget imperdiet nec, <a href="http://google.com/">pharetra </a>vel velit. Sed at euismod nibh. Praesent lacus tellus, posuere et convallis a, mollis et tellus.</p>
+<pre><code>&lt;?php
+class DataTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this-&gt;assertEquals($c, $a + $b);
+ }
+
+ public function provider()
+ {
+ return array(
+ array(0, 0, 0),
+ array(0, 1, 1),
+ array(1, 0, 1),
+ array(1, 1, 3)
+ );
+ }
+}</code></pre><ul><li>Suspendisse potenti. Phasellus tincidunt dignissim est eget mattis.</li>
+ <li>Vestibulum lacinia condimentum tellus, non vestibulum erat dapibus quis.</li>
+ <li>Aliquam arcu nibh, <a href="http://google.com/">viverra</a> adipiscing eleifend quis, pretium vitae ipsum.</li>
+ <li>Curabitur turpis ante, congue ac <a href="http://google.com/">dapibus quis</a>, vehicula ac orci.</li>
+</ul>
+<p>Nunc luctus neque non massa porta sed pharetra ante accumsan. Nam suscipit risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor. Donec at massa ante, sagittis fermentum urna.</p>
+
+<p><object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed type="application/x-shockwave-flash" width="480" height="390" src="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
+<h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h2>
+<p><img class="alignright size-thumbnail wp-image-905" title="Surest Things mixing session in Adobe Audition" src="http://www.mrclay.org/wp-content/uploads/2010/09/surestThings_audition-150x150.png" alt="screenshot of Audition mixing session" width="150" height="150">Vivamus enim ante, <em>mattis eget imperdiet nec, pharetra vel velit.</em> Sed at euismod nibh. Praesent lacus tellus, <a href="http://google.com/">posuere et convallis</a> a, <strong>mollis et tellus. Suspendisse potenti</strong>. Phasellus tincidunt dignissim est eget mattis. Vestibulum lacinia <del>condimentum tellus, non vestibulum erat dapibus</del> quis. Aliquam arcu nibh, viverra adipiscing eleifend quis, pretium vitae ipsum.</p>
+
+<p>Curabitur turpis ante, <span style="color: #993300;">congue ac dapibus quis, vehicula ac orci.</span> Nunc luctus neque non massa porta sed pharetra ante accumsan. <a href="http://google.com/">Nam suscipit</a> risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor.</p>
+<h3>Donec at massa ante, sagittis fermentum urna.</h3><blockquote>
+<p>Mauris volutpat est id massa volutpat lacinia. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In in nisl mauris. In aliquet pretium nisl, vel convallis neque cursus vitae. Curabitur id mauris in urna gravida ornare.</p>
+
+<p>[caption id="attachment_719" align="alignleft" width="150" caption="Ibanez AGB140 Bass"]<img class="size-thumbnail wp-image-719" title="Ibanez AGB140 Bass" src="http://www.mrclay.org/wp-content/uploads/2010/04/agb140-e1271773766573-150x150.jpg" alt="Ibanez AGB140 Bass" width="150" height="150">[/caption]</p>
+
+<p>Aenean <a href="http://google.com/">aliquet cursus purus sed gravida. Cras auctor euismod justo, ac dictum purus facilisis dignissim.</a> Quisque facilisis porta sem, ac suscipit quam molestie nec. Pellentesque quis hendrerit enim. Vivamus tempor erat diam. Sed eu felis nunc. Cras posuere lorem commodo turpis mollis sagittis. Mauris lobortis nunc felis.</p>
+
+<p>Maecenas elit lorem, varius sed condimentum ac, cursus et magna. Nam ut massa id augue consectetur porttitor eleifend in nunc. Curabitur cursus varius dictum. Vestibulum vel justo et neque tempus placerat a vel sapien.</p>
+</blockquote>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus enim ante, mattis eget imperdiet nec, <a href="http://google.com/">pharetra </a>vel velit. Sed at euismod nibh. Praesent lacus tellus, posuere et convallis a, mollis et tellus.</p>
+<pre><code>&lt;?php
+class DataTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this-&gt;assertEquals($c, $a + $b);
+ }
+
+ public function provider()
+ {
+ return array(
+ array(0, 0, 0),
+ array(0, 1, 1),
+ array(1, 0, 1),
+ array(1, 1, 3)
+ );
+ }
+}</code></pre><ul><li>Suspendisse potenti. Phasellus tincidunt dignissim est eget mattis.</li>
+ <li>Vestibulum lacinia condimentum tellus, non vestibulum erat dapibus quis.</li>
+ <li>Aliquam arcu nibh, <a href="http://google.com/">viverra</a> adipiscing eleifend quis, pretium vitae ipsum.</li>
+ <li>Curabitur turpis ante, congue ac <a href="http://google.com/">dapibus quis</a>, vehicula ac orci.</li>
+</ul>
+<p>Nunc luctus neque non massa porta sed pharetra ante accumsan. Nam suscipit risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor. Donec at massa ante, sagittis fermentum urna.</p>
+
+<p><object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed type="application/x-shockwave-flash" width="480" height="390" src="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
diff --git a/engine/tests/test_files/output/autop/typical-post.in.html b/engine/tests/test_files/output/autop/typical-post.in.html
new file mode 100644
index 000000000..6e4984cc4
--- /dev/null
+++ b/engine/tests/test_files/output/autop/typical-post.in.html
@@ -0,0 +1,89 @@
+<h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h2>
+<img class="alignright size-thumbnail wp-image-905" title="Surest Things mixing session in Adobe Audition" src="http://www.mrclay.org/wp-content/uploads/2010/09/surestThings_audition-150x150.png" alt="screenshot of Audition mixing session" width="150" height="150" />Vivamus enim ante, <em>mattis eget imperdiet nec, pharetra vel velit.</em> Sed at euismod nibh. Praesent lacus tellus, <a href="http://google.com/">posuere et convallis</a> a, <strong>mollis et tellus. Suspendisse potenti</strong>. Phasellus tincidunt dignissim est eget mattis. Vestibulum lacinia <del>condimentum tellus, non vestibulum erat dapibus</del> quis. Aliquam arcu nibh, viverra adipiscing eleifend quis, pretium vitae ipsum.
+
+Curabitur turpis ante, <span style="color: #993300;">congue ac dapibus quis, vehicula ac orci.</span> Nunc luctus neque non massa porta sed pharetra ante accumsan. <a href="http://google.com/">Nam suscipit</a> risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor.
+<h3>Donec at massa ante, sagittis fermentum urna.</h3>
+<blockquote>Mauris volutpat est id massa volutpat lacinia. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In in nisl mauris. In aliquet pretium nisl, vel convallis neque cursus vitae. Curabitur id mauris in urna gravida ornare.
+
+[caption id="attachment_719" align="alignleft" width="150" caption="Ibanez AGB140 Bass"]<img class="size-thumbnail wp-image-719" title="Ibanez AGB140 Bass" src="http://www.mrclay.org/wp-content/uploads/2010/04/agb140-e1271773766573-150x150.jpg" alt="Ibanez AGB140 Bass" width="150" height="150" />[/caption]
+
+Aenean <a href="http://google.com/">aliquet cursus purus sed gravida. Cras auctor euismod justo, ac dictum purus facilisis dignissim.</a> Quisque facilisis porta sem, ac suscipit quam molestie nec. Pellentesque quis hendrerit enim. Vivamus tempor erat diam. Sed eu felis nunc. Cras posuere lorem commodo turpis mollis sagittis. Mauris lobortis nunc felis.
+
+Maecenas elit lorem, varius sed condimentum ac, cursus et magna. Nam ut massa id augue consectetur porttitor eleifend in nunc. Curabitur cursus varius dictum. Vestibulum vel justo et neque tempus placerat a vel sapien.</blockquote>
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus enim ante, mattis eget imperdiet nec, <a href="http://google.com/">pharetra </a>vel velit. Sed at euismod nibh. Praesent lacus tellus, posuere et convallis a, mollis et tellus.
+
+<pre><code>&lt;?php
+class DataTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this-&gt;assertEquals($c, $a + $b);
+ }
+
+ public function provider()
+ {
+ return array(
+ array(0, 0, 0),
+ array(0, 1, 1),
+ array(1, 0, 1),
+ array(1, 1, 3)
+ );
+ }
+}</code></pre>
+<ul>
+ <li>Suspendisse potenti. Phasellus tincidunt dignissim est eget mattis.</li>
+ <li>Vestibulum lacinia condimentum tellus, non vestibulum erat dapibus quis.</li>
+ <li>Aliquam arcu nibh, <a href="http://google.com/">viverra</a> adipiscing eleifend quis, pretium vitae ipsum.</li>
+ <li>Curabitur turpis ante, congue ac <a href="http://google.com/">dapibus quis</a>, vehicula ac orci.</li>
+</ul>
+Nunc luctus neque non massa porta sed pharetra ante accumsan. Nam suscipit risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor. Donec at massa ante, sagittis fermentum urna.
+
+<object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed type="application/x-shockwave-flash" width="480" height="390" src="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US" allowfullscreen="true" allowscriptaccess="always"></embed></object>
+
+<h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h2>
+<img class="alignright size-thumbnail wp-image-905" title="Surest Things mixing session in Adobe Audition" src="http://www.mrclay.org/wp-content/uploads/2010/09/surestThings_audition-150x150.png" alt="screenshot of Audition mixing session" width="150" height="150" />Vivamus enim ante, <em>mattis eget imperdiet nec, pharetra vel velit.</em> Sed at euismod nibh. Praesent lacus tellus, <a href="http://google.com/">posuere et convallis</a> a, <strong>mollis et tellus. Suspendisse potenti</strong>. Phasellus tincidunt dignissim est eget mattis. Vestibulum lacinia <del>condimentum tellus, non vestibulum erat dapibus</del> quis. Aliquam arcu nibh, viverra adipiscing eleifend quis, pretium vitae ipsum.
+
+Curabitur turpis ante, <span style="color: #993300;">congue ac dapibus quis, vehicula ac orci.</span> Nunc luctus neque non massa porta sed pharetra ante accumsan. <a href="http://google.com/">Nam suscipit</a> risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor.
+<h3>Donec at massa ante, sagittis fermentum urna.</h3>
+<blockquote>Mauris volutpat est id massa volutpat lacinia. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In in nisl mauris. In aliquet pretium nisl, vel convallis neque cursus vitae. Curabitur id mauris in urna gravida ornare.
+
+[caption id="attachment_719" align="alignleft" width="150" caption="Ibanez AGB140 Bass"]<img class="size-thumbnail wp-image-719" title="Ibanez AGB140 Bass" src="http://www.mrclay.org/wp-content/uploads/2010/04/agb140-e1271773766573-150x150.jpg" alt="Ibanez AGB140 Bass" width="150" height="150" />[/caption]
+
+Aenean <a href="http://google.com/">aliquet cursus purus sed gravida. Cras auctor euismod justo, ac dictum purus facilisis dignissim.</a> Quisque facilisis porta sem, ac suscipit quam molestie nec. Pellentesque quis hendrerit enim. Vivamus tempor erat diam. Sed eu felis nunc. Cras posuere lorem commodo turpis mollis sagittis. Mauris lobortis nunc felis.
+
+Maecenas elit lorem, varius sed condimentum ac, cursus et magna. Nam ut massa id augue consectetur porttitor eleifend in nunc. Curabitur cursus varius dictum. Vestibulum vel justo et neque tempus placerat a vel sapien.</blockquote>
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus enim ante, mattis eget imperdiet nec, <a href="http://google.com/">pharetra </a>vel velit. Sed at euismod nibh. Praesent lacus tellus, posuere et convallis a, mollis et tellus.
+
+<pre><code>&lt;?php
+class DataTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this-&gt;assertEquals($c, $a + $b);
+ }
+
+ public function provider()
+ {
+ return array(
+ array(0, 0, 0),
+ array(0, 1, 1),
+ array(1, 0, 1),
+ array(1, 1, 3)
+ );
+ }
+}</code></pre>
+<ul>
+ <li>Suspendisse potenti. Phasellus tincidunt dignissim est eget mattis.</li>
+ <li>Vestibulum lacinia condimentum tellus, non vestibulum erat dapibus quis.</li>
+ <li>Aliquam arcu nibh, <a href="http://google.com/">viverra</a> adipiscing eleifend quis, pretium vitae ipsum.</li>
+ <li>Curabitur turpis ante, congue ac <a href="http://google.com/">dapibus quis</a>, vehicula ac orci.</li>
+</ul>
+Nunc luctus neque non massa porta sed pharetra ante accumsan. Nam suscipit risus quis libero convallis viverra. Ut at arcu enim, vel pharetra dolor. Donec at massa ante, sagittis fermentum urna.
+
+<object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed type="application/x-shockwave-flash" width="480" height="390" src="http://www.youtube.com/v/zW9YOMaVTFI?fs=1&amp;hl=en_US" allowfullscreen="true" allowscriptaccess="always"></embed></object> \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/wp-welcome.exp.html b/engine/tests/test_files/output/autop/wp-welcome.exp.html
new file mode 100644
index 000000000..2f612e3dd
--- /dev/null
+++ b/engine/tests/test_files/output/autop/wp-welcome.exp.html
@@ -0,0 +1,22 @@
+
+<p>Welcome to WordPress! This post contains important information. After you read it, you can make it private to hide it from visitors but still have the information handy for future reference.</p>
+
+<p>First things first:</p>
+<ul><li><a href="%1%24s" title="Subscribe to the WordPress mailing list for Release Notifications">Subscribe to the WordPress mailing list for release notifications</a></li>
+</ul>
+<p>As a subscriber, you will receive an email every time an update is available (and only then). This will make it easier to keep your site up to date, and secure from evildoers.<br />When a new version is released, <a href="%2%24s" title="If you are already logged in, this will take you directly to the Dashboard">log in to the Dashboard</a> and follow the instructions.<br />Upgrading is a couple of clicks!</p>
+
+<p>Then you can start enjoying the WordPress experience:</p>
+<ul><li>Edit your personal information at <a href="%3%24s" title="Edit settings like your password, your display name and your contact information">Users &#8250; Your Profile</a></li>
+ <li>Start publishing at <a href="%4%24s" title="Create a new post">Posts &#8250; Add New</a> and at <a href="%5%24s" title="Create a new page">Pages &#8250; Add New</a></li>
+ <li>Browse and install plugins at <a href="%6%24s" title="Browse and install plugins at the official WordPress repository directly from your Dashboard">Plugins &#8250; Add New</a></li>
+ <li>Browse and install themes at <a href="%7%24s" title="Browse and install themes at the official WordPress repository directly from your Dashboard">Appearance &#8250; Add New Themes</a></li>
+ <li>Modify and prettify your website&#8217;s links at <a href="%8%24s" title="For example, select a link structure like: http://example.com/1999/12/post-name">Settings &#8250; Permalinks</a></li>
+ <li>Import content from another system or WordPress site at <a href="%9%24s" title="WordPress comes with importers for the most common publishing systems">Tools &#8250; Import</a></li>
+ <li>Find answers to your questions at the <a href="%10%24s" title="The official WordPress documentation, maintained by the WordPress community">WordPress Codex</a></li>
+</ul>
+<p>To keep this post for reference, <a href="%11%24s" title="Click to edit the content and settings of this post">click to edit it</a>, go to the Publish box and change its Visibility from Public to Private.</p>
+
+<p>Thank you for selecting WordPress. We wish you happy publishing!</p>
+
+<p>PS. Not yet subscribed for update notifications? <a href="%1%24s" title="Subscribe to the WordPress mailing list for Release Notifications">Do it now!</a></p>
diff --git a/engine/tests/test_files/output/autop/wp-welcome.in.html b/engine/tests/test_files/output/autop/wp-welcome.in.html
new file mode 100644
index 000000000..338ede73f
--- /dev/null
+++ b/engine/tests/test_files/output/autop/wp-welcome.in.html
@@ -0,0 +1,25 @@
+Welcome to WordPress! This post contains important information. After you read it, you can make it private to hide it from visitors but still have the information handy for future reference.
+
+First things first:
+<ul>
+ <li><a href="%1$s" title="Subscribe to the WordPress mailing list for Release Notifications">Subscribe to the WordPress mailing list for release notifications</a></li>
+</ul>
+As a subscriber, you will receive an email every time an update is available (and only then). This will make it easier to keep your site up to date, and secure from evildoers.
+When a new version is released, <a href="%2$s" title="If you are already logged in, this will take you directly to the Dashboard">log in to the Dashboard</a> and follow the instructions.
+Upgrading is a couple of clicks!
+
+Then you can start enjoying the WordPress experience:
+<ul>
+ <li>Edit your personal information at <a href="%3$s" title="Edit settings like your password, your display name and your contact information">Users &#8250; Your Profile</a></li>
+ <li>Start publishing at <a href="%4$s" title="Create a new post">Posts &#8250; Add New</a> and at <a href="%5$s" title="Create a new page">Pages &#8250; Add New</a></li>
+ <li>Browse and install plugins at <a href="%6$s" title="Browse and install plugins at the official WordPress repository directly from your Dashboard">Plugins &#8250; Add New</a></li>
+ <li>Browse and install themes at <a href="%7$s" title="Browse and install themes at the official WordPress repository directly from your Dashboard">Appearance &#8250; Add New Themes</a></li>
+ <li>Modify and prettify your website&#8217;s links at <a href="%8$s" title="For example, select a link structure like: http://example.com/1999/12/post-name">Settings &#8250; Permalinks</a></li>
+ <li>Import content from another system or WordPress site at <a href="%9$s" title="WordPress comes with importers for the most common publishing systems">Tools &#8250; Import</a></li>
+ <li>Find answers to your questions at the <a href="%10$s" title="The official WordPress documentation, maintained by the WordPress community">WordPress Codex</a></li>
+</ul>
+To keep this post for reference, <a href="%11$s" title="Click to edit the content and settings of this post">click to edit it</a>, go to the Publish box and change its Visibility from Public to Private.
+
+Thank you for selecting WordPress. We wish you happy publishing!
+
+PS. Not yet subscribed for update notifications? <a href="%1$s" title="Subscribe to the WordPress mailing list for Release Notifications">Do it now!</a>
diff --git a/engine/tests/test_files/output/autop/wpautop-fails.exp.html b/engine/tests/test_files/output/autop/wpautop-fails.exp.html
new file mode 100644
index 000000000..d018db4ff
--- /dev/null
+++ b/engine/tests/test_files/output/autop/wpautop-fails.exp.html
@@ -0,0 +1,31 @@
+
+<p>paragraph</p>
+
+<p>paragraph</p>
+<div class="whatever"><blockquote>
+<p>paragraph</p>
+</blockquote>
+<p>line</p>
+</div>
+<p>paragraph</p>
+<ul><li>line</li>
+<li>paragraph
+
+paragraph</li>
+</ul>
+<p>paragraph<br />line<br />line</p>
+<pre>Honor
+this whitespace
+</pre>
+<p>paragraph</p>
+<style><!--
+Do not alter!
+--></style>
+<p>paragraph <!-- do not alter --></p>
+<dl><dt>term</dt> <dd>paragraph
+
+<a href="xx"> <img src="yy"></a>
+
+paragraph</dd> </dl><div><a href="xx"> <img src="yy"></a></div>
+<p>Hello <a href="link"><br /><br />World</a></p>
+<p id="abc">Paragraph</p><div>Line</div> \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/wpautop-fails.in.html b/engine/tests/test_files/output/autop/wpautop-fails.in.html
new file mode 100644
index 000000000..9aa24be59
--- /dev/null
+++ b/engine/tests/test_files/output/autop/wpautop-fails.in.html
@@ -0,0 +1,41 @@
+
+paragraph
+
+paragraph <div class="whatever"><blockquote>
+ paragraph
+ </blockquote>
+ line
+</div>
+
+paragraph
+<ul>
+<li>line</li>
+<li>paragraph
+
+paragraph</li>
+</ul>
+paragraph
+line<br>
+ line
+<pre>Honor
+this whitespace
+</pre>
+paragraph
+<style><!--
+Do not alter!
+--></style>
+paragraph <!-- do not alter -->
+<dl> <dt>term</dt> <dd>paragraph
+
+<a href="xx"> <img src="yy" /> </a>
+
+paragraph</dd> </dl>
+<div><a href="xx"> <img src="yy" /> </a></div>
+
+Hello <a href="link">
+
+World</a>
+
+<p id="abc">Paragraph</p>
+
+<div>Line</div> \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/wysiwyg-test.exp.html b/engine/tests/test_files/output/autop/wysiwyg-test.exp.html
new file mode 100644
index 000000000..1f23d6154
--- /dev/null
+++ b/engine/tests/test_files/output/autop/wysiwyg-test.exp.html
@@ -0,0 +1,51 @@
+
+<p>&nbps;<br />&#8820;</p>
+<h1>h1</h1>
+<p>Paragraph <a href="http://google.com/">link</a> <strong>Bold</strong> <em>italic</em> <em><strong>bolditalic</strong></em>&nbsp;<span style="background-color: #ffff00; "></span></p>
+<h2>h2</h2>
+<p>Paragraph <span style="font-size: xx-small;">size1</span> <span style="font-size: x-small;">size2</span> <span style="font-size: medium;">size4</span></p>
+<h3>h3</h3>
+<p>Paragraph <span style="text-decoration: underline;">underline</span> <span style="text-decoration: line-through;">strikethrough</span> <span style="color: #ff0000;">color</span> <span style="background-color: #ffff00; ">background</span></p>
+<blockquote>
+<p>Blockquoted paragraph</p>
+</blockquote>
+<p>Paragraph following blockquote</p>
+<ul><li>Unordered</li>
+ <li>List</li>
+</ul>
+<p>Paragraph between lists</p>
+<ol><li>Ordered</li>
+ <li>List</li>
+</ol>
+<p>Paragraph between lists</p>
+<ul><li>OL list</li>
+ <li>nested
+ <ol><li>inside a</li>
+ <li>UL list</li>
+ </ol></li>
+</ul>
+<p>Paragraph between lists</p>
+<table border="0"><tbody><tr></tr><tr><td>Table with</td>
+ <td></td>
+ </tr><tr><td></td>
+ <td>border=0</td>
+ </tr></tbody></table>
+<p>Paragraph</p>
+<ol><li>UL list</li>
+ <li>nested
+ <ul><li>inside a</li>
+ <li>OL list</li>
+ </ul></li>
+</ol>
+<p>Paragraph between tables</p>
+<table border="1" cellpadding="5"><tbody><tr><td>Table with border=1</td>
+ <td></td>
+ </tr><tr><td></td>
+ <td>cellpadding = 5</td>
+ </tr></tbody></table>
+<p>Paragraph between tables</p>
+<table border="2"><tbody><tr><td>Table with</td>
+ <td></td>
+ </tr><tr><td></td>
+ <td>border=2</td>
+ </tr></tbody></table> \ No newline at end of file
diff --git a/engine/tests/test_files/output/autop/wysiwyg-test.in.html b/engine/tests/test_files/output/autop/wysiwyg-test.in.html
new file mode 100644
index 000000000..733b0e2ec
--- /dev/null
+++ b/engine/tests/test_files/output/autop/wysiwyg-test.in.html
@@ -0,0 +1,79 @@
+&nbps;
+&#8820;
+<h1>h1</h1>
+Paragraph <a href="http://google.com/">link</a> <strong>Bold</strong> <em>italic</em> <em><strong>bolditalic</strong></em>&nbsp;<span style="background-color: #ffff00; "></span>
+<h2>h2</h2>
+Paragraph <span style="font-size: xx-small;">size1</span> <span style="font-size: x-small;">size2</span> <span style="font-size: medium;">size4</span>
+<h3>h3</h3>
+Paragraph <span style="text-decoration: underline;">underline</span> <span style="text-decoration: line-through;">strikethrough</span> <span style="color: #ff0000;">color</span> <span style="background-color: #ffff00; ">background</span>
+<blockquote>Blockquoted paragraph</blockquote>
+Paragraph following blockquote
+<ul>
+ <li>Unordered</li>
+ <li>List</li>
+</ul>
+Paragraph between lists
+<ol>
+ <li>Ordered</li>
+ <li>List</li>
+</ol>
+Paragraph between lists
+<ul>
+ <li>OL list</li>
+ <li>nested
+ <ol>
+ <li>inside a</li>
+ <li>UL list</li>
+ </ol></li>
+</ul>
+Paragraph between lists
+<table border="0">
+ <tbody>
+ <tr>
+ </tr>
+ <tr>
+ <td>Table with</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>border=0</td>
+ </tr>
+ </tbody>
+</table>
+Paragraph
+<ol>
+ <li>UL list</li>
+ <li>nested
+ <ul>
+ <li>inside a</li>
+ <li>OL list</li>
+ </ul>
+ </li>
+</ol>
+Paragraph between tables
+<table border="1" cellpadding="5">
+ <tbody>
+ <tr>
+ <td>Table with border=1</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>cellpadding = 5</td>
+ </tr>
+ </tbody>
+</table>
+Paragraph between tables
+<table border="2">
+ <tbody>
+ <tr>
+ <td>Table with</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>border=2</td>
+ </tr>
+ </tbody>
+</table> \ No newline at end of file
diff --git a/install/ElggInstaller.php b/install/ElggInstaller.php
index 03c84a43e..934b38d28 100644
--- a/install/ElggInstaller.php
+++ b/install/ElggInstaller.php
@@ -157,7 +157,7 @@ class ElggInstaller {
'password',
);
foreach ($requiredParams as $key) {
- if (!array_key_exists($key, $params)) {
+ if (empty($params[$key])) {
$msg = elgg_echo('install:error:requiredfield', array($key));
throw new InstallationException($msg);
}
diff --git a/install/cli/sample_installer.php b/install/cli/sample_installer.php
index 954169a6a..0bae0cd23 100644
--- a/install/cli/sample_installer.php
+++ b/install/cli/sample_installer.php
@@ -3,10 +3,27 @@
* Sample cli installer script
*/
+$enabled = false;
+
+// Do not edit below this line. //////////////////////////////
+
+
+if (!$enabled) {
+ echo "To enable this script, change \$enabled to true.\n";
+ echo "You *must* disable this script after a successful installation.\n";
+ exit;
+}
+
+if (PHP_SAPI !== 'cli') {
+ echo "You must use the command line to run this script.";
+ exit;
+}
+
require_once(dirname(dirname(__FILE__)) . "/ElggInstaller.php");
$installer = new ElggInstaller();
+// none of the following may be empty
$params = array(
// database parameters
'dbuser' => '',
@@ -28,3 +45,21 @@ $params = array(
// install and create the .htaccess file
$installer->batchInstall($params, TRUE);
+
+// at this point installation has completed (otherwise an exception halted execution).
+
+// try to rewrite the script to disable it.
+if (is_writable(__FILE__)) {
+ $code = file_get_contents(__FILE__);
+ if (preg_match('~\\$enabled\\s*=\\s*(true|1)\\s*;~i', $code)) {
+ // looks safe to rewrite
+ $code = preg_replace('~\\$enabled\\s*=\\s*(true|1)\\s*;~i', '$enabled = false;', $code);
+ file_put_contents(__FILE__, $code);
+
+ echo "\nNote: This script has been disabled for your safety.\n";
+ exit;
+ }
+}
+
+echo "\nWarning: You *must* disable this script by setting \$enabled = false;.\n";
+echo "Leaving this script enabled could endanger your installation.\n";
diff --git a/js/lib/ui.js b/js/lib/ui.js
index 616e71d54..2a4d269d6 100644
--- a/js/lib/ui.js
+++ b/js/lib/ui.js
@@ -283,7 +283,7 @@ elgg.ui.initDatePicker = function() {
dataType: "script",
cache: true,
success: loadDatePicker,
- error: loadDatePicker, // english language is already loaded.
+ error: loadDatePicker // english language is already loaded.
});
}
};
diff --git a/js/tests/ElggLibTest.js b/js/tests/ElggLibTest.js
index a29ebf743..2a676e22a 100644
--- a/js/tests/ElggLibTest.js
+++ b/js/tests/ElggLibTest.js
@@ -99,7 +99,7 @@ ElggLibTest.prototype.testNormalizeUrl = function() {
['/mod/plugin/file.php', elgg.config.wwwroot + 'mod/plugin/file.php'],
['/mod/plugin/file.php?p=v&p2=v2', elgg.config.wwwroot + 'mod/plugin/file.php?p=v&p2=v2'],
['/rootfile.php', elgg.config.wwwroot + 'rootfile.php'],
- ['/rootfile.php?p=v&p2=v2', elgg.config.wwwroot + 'rootfile.php?p=v&p2=v2'],
+ ['/rootfile.php?p=v&p2=v2', elgg.config.wwwroot + 'rootfile.php?p=v&p2=v2']
].forEach(function(args) {
assertEquals(args[1], elgg.normalize_url(args[0]));
diff --git a/languages/en.php b/languages/en.php
index bb5376a44..2b5ba00fd 100644
--- a/languages/en.php
+++ b/languages/en.php
@@ -229,6 +229,7 @@ $english = array(
'LoginException:PasswordFailure' => 'We could not log you in. Please check your username/email and password.',
'LoginException:AccountLocked' => 'Your account has been locked for too many log in failures.',
'LoginException:ChangePasswordFailure' => 'Failed current password check.',
+ 'LoginException:Unknown' => 'We could not log you in due to an unknown error.',
'deprecatedfunction' => 'Warning: This code uses the deprecated function \'%s\' and is not compatible with this version of Elgg',
@@ -581,6 +582,7 @@ $english = array(
'admin:users' => "Users",
'admin:users:online' => 'Currently Online',
'admin:users:newest' => 'Newest',
+ 'admin:users:admins' => 'Administrators',
'admin:users:add' => 'Add New User',
'admin:users:description' => "This admin panel allows you to control user settings for your site. Choose an option below to get started.",
'admin:users:adduser:label' => "Click here to add a new user...",
@@ -732,6 +734,7 @@ $english = array(
'admin:statistics:label:numusers' => "Number of users",
'admin:statistics:label:numonline' => "Number of users online",
'admin:statistics:label:onlineusers' => "Users online now",
+ 'admin:statistics:label:admins'=>"Admins",
'admin:statistics:label:version' => "Elgg version",
'admin:statistics:label:version:release' => "Release",
'admin:statistics:label:version:version' => "Version",
diff --git a/mod/blog/lib/blog.php b/mod/blog/lib/blog.php
index 4622a9e7e..3c71dfbab 100644
--- a/mod/blog/lib/blog.php
+++ b/mod/blog/lib/blog.php
@@ -50,7 +50,7 @@ function blog_get_page_content_read($guid = NULL) {
/**
* Get page components to list a user's or all blogs.
*
- * @param int $owner_guid The GUID of the page owner or NULL for all blogs
+ * @param int $container_guid The GUID of the page owner or NULL for all blogs
* @return array
*/
function blog_get_page_content_list($container_guid = NULL) {
@@ -62,10 +62,11 @@ function blog_get_page_content_list($container_guid = NULL) {
$options = array(
'type' => 'object',
'subtype' => 'blog',
- 'full_view' => FALSE,
+ 'full_view' => false,
);
- $loggedin_userid = elgg_get_logged_in_user_guid();
+ $current_user = elgg_get_logged_in_user_entity();
+
if ($container_guid) {
// access check for closed groups
group_gatekeeper();
@@ -80,7 +81,7 @@ function blog_get_page_content_list($container_guid = NULL) {
$crumbs_title = $container->name;
elgg_push_breadcrumb($crumbs_title);
- if ($container_guid == $loggedin_userid) {
+ if ($current_user && ($container_guid == $current_user->guid)) {
$return['filter_context'] = 'mine';
} else if (elgg_instanceof($container, 'group')) {
$return['filter'] = false;
@@ -99,7 +100,13 @@ function blog_get_page_content_list($container_guid = NULL) {
// show all posts for admin or users looking at their own blogs
// show only published posts for other users.
- if (!(elgg_is_admin_logged_in() || (elgg_is_logged_in() && $container_guid == $loggedin_userid))) {
+ $show_only_published = true;
+ if ($current_user) {
+ if (($current_user->guid == $container_guid) || $current_user->isAdmin()) {
+ $show_only_published = false;
+ }
+ }
+ if ($show_only_published) {
$options['metadata_name_value_pairs'] = array(
array('name' => 'status', 'value' => 'published'),
);
@@ -155,11 +162,14 @@ function blog_get_page_content_friends($user_guid) {
// admin / owners can see any posts
// everyone else can only see published posts
- if (!(elgg_is_admin_logged_in() || (elgg_is_logged_in() && $owner_guid == elgg_get_logged_in_user_guid()))) {
- if ($upper > $now) {
- $upper = $now;
+ $show_only_published = true;
+ $current_user = elgg_get_logged_in_user_entity();
+ if ($current_user) {
+ if (($user_guid == $current_user->guid) || $current_user->isAdmin()) {
+ $show_only_published = false;
}
-
+ }
+ if ($show_only_published) {
$options['metadata_name_value_pairs'][] = array(
array('name' => 'status', 'value' => 'published')
);
@@ -240,9 +250,9 @@ function blog_get_page_content_archive($owner_guid, $lower = 0, $upper = 0) {
$list = elgg_list_entities_from_metadata($options);
if (!$list) {
- $content .= elgg_echo('blog:none');
+ $content = elgg_echo('blog:none');
} else {
- $content .= $list;
+ $content = $list;
}
$title = elgg_echo('date:month:' . date('m', $lower), array(date('Y', $lower)));
@@ -274,6 +284,7 @@ function blog_get_page_content_edit($page, $guid = 0, $revision = NULL) {
$vars['id'] = 'blog-post-edit';
$vars['class'] = 'elgg-form-alt';
+ $sidebar = '';
if ($page == 'edit') {
$blog = get_entity((int)$guid);
@@ -310,14 +321,8 @@ function blog_get_page_content_edit($page, $guid = 0, $revision = NULL) {
$content = elgg_echo('blog:error:cannot_edit_post');
}
} else {
- if (!$guid) {
- $container = elgg_get_logged_in_user_entity();
- } else {
- $container = get_entity($guid);
- }
-
elgg_push_breadcrumb(elgg_echo('blog:add'));
- $body_vars = blog_prepare_form_vars($blog);
+ $body_vars = blog_prepare_form_vars(null);
$title = elgg_echo('blog:add');
$content = elgg_view_form('blog/save', $vars, $body_vars);
@@ -384,7 +389,7 @@ function blog_prepare_form_vars($post = NULL, $revision = NULL) {
if ($auto_save_annotations = $post->getAnnotations('blog_auto_save', 1)) {
$auto_save = $auto_save_annotations[0];
} else {
- $auto_save == FALSE;
+ $auto_save = false;
}
if ($auto_save && $auto_save->id != $revision->id) {
@@ -396,52 +401,74 @@ function blog_prepare_form_vars($post = NULL, $revision = NULL) {
/**
* Forward to the new style of URLs
+ *
+ * Pre-1.7.5
+ * Group blogs page: /blog/group:<container_guid>/
+ * Group blog view: /blog/group:<container_guid>/read/<guid>/<title>
+ * 1.7.5-1.8
+ * Group blogs page: /blog/owner/group:<container_guid>/
+ * Group blog view: /blog/read/<guid>
+ *
*
* @param string $page
*/
function blog_url_forwarder($page) {
- global $CONFIG;
+
+ $viewtype = elgg_get_viewtype();
+ $qs = ($viewtype === 'default') ? "" : "?view=$viewtype";
+
+ $url = "blog/all";
+
+ // easier to work with & no notices
+ $page = array_pad($page, 4, "");
// group usernames
- if (substr_count($page[0], 'group:')) {
- preg_match('/group\:([0-9]+)/i', $page[0], $matches);
+ if (preg_match('~/group\:([0-9]+)/~', "/{$page[0]}/{$page[1]}/", $matches)) {
$guid = $matches[1];
$entity = get_entity($guid);
- if ($entity) {
- $url = "{$CONFIG->wwwroot}blog/group/$guid/all";
+ if (elgg_instanceof($entity, 'group')) {
+ if (!empty($page[2])) {
+ $url = "blog/view/$page[2]/";
+ } else {
+ $url = "blog/group/$guid/all";
+ }
register_error(elgg_echo("changebookmark"));
- forward($url);
+ forward($url . $qs);
}
}
+ if (empty($page[0])) {
+ return;
+ }
+
// user usernames
$user = get_user_by_username($page[0]);
if (!$user) {
return;
}
- if (!isset($page[1])) {
+ if (empty($page[1])) {
$page[1] = 'owner';
}
switch ($page[1]) {
case "read":
- $url = "{$CONFIG->wwwroot}blog/view/{$page[2]}/{$page[3]}";
+ $url = "blog/view/{$page[2]}/{$page[3]}";
break;
case "archive":
- $url = "{$CONFIG->wwwroot}blog/archive/{$page[0]}/{$page[2]}/{$page[3]}";
+ $url = "blog/archive/{$page[0]}/{$page[2]}/{$page[3]}";
break;
case "friends":
- $url = "{$CONFIG->wwwroot}blog/friends/{$page[0]}";
+ $url = "blog/friends/{$page[0]}";
break;
case "new":
- $url = "{$CONFIG->wwwroot}blog/add/$user->guid";
+ $url = "blog/add/$user->guid";
break;
case "owner":
- $url = "{$CONFIG->wwwroot}blog/owner/{$page[0]}";
+ $url = "blog/owner/{$page[0]}";
break;
}
register_error(elgg_echo("changebookmark"));
- forward($url);
+ forward($url . $qs);
}
diff --git a/mod/blog/start.php b/mod/blog/start.php
index 9faf1794e..8cbaf5cca 100644
--- a/mod/blog/start.php
+++ b/mod/blog/start.php
@@ -99,8 +99,7 @@ function blog_page_handler($page) {
elgg_load_library('elgg:blog');
- // @todo remove the forwarder in 1.9
- // forward to correct URL for blog pages pre-1.7.5
+ // forward to correct URL for blog pages pre-1.8
blog_url_forwarder($page);
// push all blogs breadcrumb
diff --git a/mod/blog/views/default/forms/blog/save.php b/mod/blog/views/default/forms/blog/save.php
index 0aefae0d9..36fa2e0e8 100644
--- a/mod/blog/views/default/forms/blog/save.php
+++ b/mod/blog/views/default/forms/blog/save.php
@@ -23,7 +23,7 @@ if ($vars['guid']) {
$delete_link = elgg_view('output/confirmlink', array(
'href' => $delete_url,
'text' => elgg_echo('delete'),
- 'class' => 'elgg-button elgg-button-delete elgg-state-disabled float-alt'
+ 'class' => 'elgg-button elgg-button-delete float-alt'
));
}
@@ -53,7 +53,7 @@ $excerpt_label = elgg_echo('blog:excerpt');
$excerpt_input = elgg_view('input/text', array(
'name' => 'excerpt',
'id' => 'blog_excerpt',
- 'value' => html_entity_decode($vars['excerpt'], ENT_COMPAT, 'UTF-8')
+ 'value' => _elgg_html_decode($vars['excerpt'])
));
$body_label = elgg_echo('blog:body');
diff --git a/mod/file/thumbnail.php b/mod/file/thumbnail.php
index 35bf8c7f7..851f13a8f 100644
--- a/mod/file/thumbnail.php
+++ b/mod/file/thumbnail.php
@@ -46,7 +46,7 @@ if ($simpletype == "image") {
// caching images for 10 days
header("Content-type: $mime");
- header('Expires: ' . date('r',time() + 864000));
+ header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+10 days")), true);
header("Pragma: public", true);
header("Cache-Control: public", true);
header("Content-Length: " . strlen($contents));
diff --git a/mod/groups/actions/groups/edit.php b/mod/groups/actions/groups/edit.php
index a4169461a..d0689be2e 100644
--- a/mod/groups/actions/groups/edit.php
+++ b/mod/groups/actions/groups/edit.php
@@ -5,27 +5,25 @@
* @package ElggGroups
*/
-// Load configuration
-global $CONFIG;
+elgg_make_sticky_form('groups');
/**
* wrapper for recursive array walk decoding
*/
function profile_array_decoder(&$v) {
- $v = html_entity_decode($v, ENT_COMPAT, 'UTF-8');
+ $v = _elgg_html_decode($v);
}
-elgg_make_sticky_form('groups');
-
// Get group fields
$input = array();
-foreach ($CONFIG->group as $shortname => $valuetype) {
- // another work around for Elgg's encoding problems: #561, #1963
+foreach (elgg_get_config('group') as $shortname => $valuetype) {
$input[$shortname] = get_input($shortname);
+
+ // @todo treat profile fields as unescaped: don't filter, encode on output
if (is_array($input[$shortname])) {
array_walk_recursive($input[$shortname], 'profile_array_decoder');
} else {
- $input[$shortname] = html_entity_decode($input[$shortname], ENT_COMPAT, 'UTF-8');
+ $input[$shortname] = _elgg_html_decode($input[$shortname]);
}
if ($valuetype == 'tags') {
@@ -38,15 +36,17 @@ $input['name'] = htmlspecialchars(get_input('name', '', false), ENT_QUOTES, 'UTF
$user = elgg_get_logged_in_user_entity();
$group_guid = (int)get_input('group_guid');
-$new_group_flag = $group_guid == 0;
+$is_new_group = $group_guid == 0;
-if ($new_group_flag && elgg_get_plugin_setting('limited_groups', 'groups') == 'yes' && !elgg_is_admin_logged_in()) {
+if ($is_new_group
+ && (elgg_get_plugin_setting('limited_groups', 'groups') == 'yes')
+ && !$user->isAdmin()) {
register_error(elgg_echo("groups:cantcreate"));
forward(REFERER);
}
$group = new ElggGroup($group_guid); // load if present, if not create a new group
-if (($group_guid) && (!$group->canEdit())) {
+if ($group_guid && !$group->canEdit()) {
register_error(elgg_echo("groups:cantedit"));
forward(REFERER);
}
@@ -61,37 +61,46 @@ if (sizeof($input) > 0) {
// Validate create
if (!$group->name) {
register_error(elgg_echo("groups:notitle"));
-
forward(REFERER);
}
// Set group tool options
-if (isset($CONFIG->group_tool_options)) {
- foreach ($CONFIG->group_tool_options as $group_option) {
- $group_option_toggle_name = $group_option->name . "_enable";
- if ($group_option->default_on) {
- $group_option_default_value = 'yes';
- } else {
- $group_option_default_value = 'no';
- }
- $group->$group_option_toggle_name = get_input($group_option_toggle_name, $group_option_default_value);
+$tool_options = elgg_get_config('group_tool_options');
+if ($tool_options) {
+ foreach ($tool_options as $group_option) {
+ $option_toggle_name = $group_option->name . "_enable";
+ $option_default = $group_option->default_on ? 'yes' : 'no';
+ $group->$option_toggle_name = get_input($option_toggle_name, $option_default);
}
}
// Group membership - should these be treated with same constants as access permissions?
-switch (get_input('membership')) {
- case ACCESS_PUBLIC:
- $group->membership = ACCESS_PUBLIC;
- break;
- default:
- $group->membership = ACCESS_PRIVATE;
-}
+$is_public_membership = (get_input('membership') == ACCESS_PUBLIC);
+$group->membership = $is_public_membership ? ACCESS_PUBLIC : ACCESS_PRIVATE;
-if ($new_group_flag) {
+if ($is_new_group) {
$group->access_id = ACCESS_PUBLIC;
}
+$old_owner_guid = $is_new_group ? 0 : $group->owner_guid;
+$new_owner_guid = (int) get_input('owner_guid');
+
+$owner_has_changed = false;
+$old_icontime = null;
+if (!$is_new_group && $new_owner_guid && $new_owner_guid != $old_owner_guid) {
+ // verify new owner is member and old owner/admin is logged in
+ if (is_group_member($group_guid, $new_owner_guid) && ($old_owner_guid == $user->guid || $user->isAdmin())) {
+ $group->owner_guid = $new_owner_guid;
+
+ // @todo Remove this when #4683 fixed
+ $owner_has_changed = true;
+ $old_icontime = $group->icontime;
+ }
+}
+
+$must_move_icons = ($owner_has_changed && $old_icontime);
+
$group->save();
// Invisible group support
@@ -115,14 +124,18 @@ $group->save();
elgg_clear_sticky_form('groups');
// group creator needs to be member of new group and river entry created
-if ($new_group_flag) {
+if ($is_new_group) {
+
+ // @todo this should not be necessary...
elgg_set_page_owner_guid($group->guid);
+
$group->join($user);
add_to_river('river/group/create', 'create', $user->guid, $group->guid, $group->access_id);
}
-// Now see if we have a file icon
-if ((isset($_FILES['icon'])) && (substr_count($_FILES['icon']['type'],'image/'))) {
+$has_uploaded_icon = (!empty($_FILES['icon']['type']) && substr_count($_FILES['icon']['type'], 'image/'));
+
+if ($has_uploaded_icon) {
$icon_sizes = elgg_get_config('icon_sizes');
@@ -134,38 +147,58 @@ if ((isset($_FILES['icon'])) && (substr_count($_FILES['icon']['type'],'image/'))
$filehandler->open("write");
$filehandler->write(get_uploaded_file('icon'));
$filehandler->close();
+ $filename = $filehandler->getFilenameOnFilestore();
+
+ $sizes = array('tiny', 'small', 'medium', 'large');
+
+ $thumbs = array();
+ foreach ($sizes as $size) {
+ $thumbs[$size] = get_resized_image_from_existing_file(
+ $filename,
+ $icon_sizes[$size]['w'],
+ $icon_sizes[$size]['h'],
+ $icon_sizes[$size]['square']
+ );
+ }
- $thumbtiny = get_resized_image_from_existing_file($filehandler->getFilenameOnFilestore(), $icon_sizes['tiny']['w'], $icon_sizes['tiny']['h'], $icon_sizes['tiny']['square']);
- $thumbsmall = get_resized_image_from_existing_file($filehandler->getFilenameOnFilestore(), $icon_sizes['small']['w'], $icon_sizes['small']['h'], $icon_sizes['small']['square']);
- $thumbmedium = get_resized_image_from_existing_file($filehandler->getFilenameOnFilestore(), $icon_sizes['medium']['w'], $icon_sizes['medium']['h'], $icon_sizes['medium']['square']);
- $thumblarge = get_resized_image_from_existing_file($filehandler->getFilenameOnFilestore(), $icon_sizes['large']['w'], $icon_sizes['large']['h'], $icon_sizes['large']['square']);
- if ($thumbtiny) {
-
+ if ($thumbs['tiny']) { // just checking if resize successful
$thumb = new ElggFile();
$thumb->owner_guid = $group->owner_guid;
$thumb->setMimeType('image/jpeg');
- $thumb->setFilename($prefix."tiny.jpg");
- $thumb->open("write");
- $thumb->write($thumbtiny);
- $thumb->close();
+ foreach ($sizes as $size) {
+ $thumb->setFilename("{$prefix}{$size}.jpg");
+ $thumb->open("write");
+ $thumb->write($thumbs[$size]);
+ $thumb->close();
+ }
- $thumb->setFilename($prefix."small.jpg");
- $thumb->open("write");
- $thumb->write($thumbsmall);
- $thumb->close();
+ $group->icontime = time();
+ }
+}
- $thumb->setFilename($prefix."medium.jpg");
- $thumb->open("write");
- $thumb->write($thumbmedium);
- $thumb->close();
+// @todo Remove this when #4683 fixed
+if ($must_move_icons) {
+ $filehandler = new ElggFile();
+ $filehandler->setFilename('groups');
+ $filehandler->owner_guid = $old_owner_guid;
+ $old_path = $filehandler->getFilenameOnFilestore();
- $thumb->setFilename($prefix."large.jpg");
- $thumb->open("write");
- $thumb->write($thumblarge);
- $thumb->close();
+ $sizes = array('', 'tiny', 'small', 'medium', 'large');
- $group->icontime = time();
+ if ($has_uploaded_icon) {
+ // delete those under old owner
+ foreach ($sizes as $size) {
+ unlink("$old_path/{$group_guid}{$size}.jpg");
+ }
+ } else {
+ // move existing to new owner
+ $filehandler->owner_guid = $group->owner_guid;
+ $new_path = $filehandler->getFilenameOnFilestore();
+
+ foreach ($sizes as $size) {
+ rename("$old_path/{$group_guid}{$size}.jpg", "$new_path/{$group_guid}{$size}.jpg");
+ }
}
}
diff --git a/mod/groups/icon.php b/mod/groups/icon.php
index 1bd240ea6..ebdc1eb6d 100644
--- a/mod/groups/icon.php
+++ b/mod/groups/icon.php
@@ -18,7 +18,7 @@ if (!($group instanceof ElggGroup)) {
// If is the same ETag, content didn't changed.
$etag = $group->icontime . $group_guid;
-if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
+if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == "\"$etag\"") {
header("HTTP/1.1 304 Not Modified");
exit;
}
@@ -46,9 +46,9 @@ if (!$success) {
}
header("Content-type: image/jpeg");
-header('Expires: ' . date('r',time() + 864000));
+header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+10 days")), true);
header("Pragma: public");
header("Cache-Control: public");
header("Content-Length: " . strlen($contents));
-header("ETag: $etag");
+header("ETag: \"$etag\"");
echo $contents;
diff --git a/mod/groups/languages/en.php b/mod/groups/languages/en.php
index 0ca980108..0d57f1680 100644
--- a/mod/groups/languages/en.php
+++ b/mod/groups/languages/en.php
@@ -35,6 +35,7 @@ $english = array(
'groups:membership' => "Group membership permissions",
'groups:access' => "Access permissions",
'groups:owner' => "Owner",
+ 'groups:owner:warning' => "Warning: if you change this value, you will no longer be the owner of this group.",
'groups:widget:num_display' => 'Number of groups to display',
'groups:widget:membership' => 'Group membership',
'groups:widgets:description' => 'Display the groups you are a member of on your profile',
diff --git a/mod/groups/views/default/forms/groups/edit.php b/mod/groups/views/default/forms/groups/edit.php
index 532e89c35..41d97e6c3 100644
--- a/mod/groups/views/default/forms/groups/edit.php
+++ b/mod/groups/views/default/forms/groups/edit.php
@@ -83,6 +83,42 @@ if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') {
<?php
}
+if (isset($vars['entity'])) {
+ $entity = $vars['entity'];
+ $owner_guid = $vars['entity']->owner_guid;
+} else {
+ $entity = false;
+}
+
+if ($entity && ($owner_guid == elgg_get_logged_in_user_guid() || elgg_is_admin_logged_in())) {
+ $owner_guid = $vars['entity']->owner_guid;
+ $members = array();
+ foreach ($vars['entity']->getMembers(0) as $member) {
+ $members[$member->guid] = "$member->name (@$member->username)";
+ }
+?>
+
+<div>
+ <label>
+ <?php echo elgg_echo('groups:owner'); ?><br />
+ <?php echo elgg_view('input/dropdown', array(
+ 'name' => 'owner_guid',
+ 'value' => $owner_guid,
+ 'options_values' => $members,
+ 'class' => 'groups-owner-input',
+ ));
+ ?>
+ </label>
+ <?php
+ if ($owner_guid == elgg_get_logged_in_user_guid()) {
+ echo '<span class="elgg-text-help">' . elgg_echo('groups:owner:warning') . '</span>';
+ }
+ ?>
+</div>
+
+<?php
+}
+
$tools = elgg_get_config('group_tool_options');
if ($tools) {
usort($tools, create_function('$a,$b', 'return strcmp($a->label,$b->label);'));
@@ -111,7 +147,7 @@ if ($tools) {
<div class="elgg-foot">
<?php
-if (isset($entity)) {
+if ($entity) {
echo elgg_view('input/hidden', array(
'name' => 'group_guid',
'value' => $entity->getGUID(),
@@ -120,7 +156,7 @@ if (isset($entity)) {
echo elgg_view('input/submit', array('value' => elgg_echo('save')));
-if (isset($entity)) {
+if ($entity) {
$delete_url = 'action/groups/delete?guid=' . $entity->getGUID();
echo elgg_view('output/confirmlink', array(
'text' => elgg_echo('groups:delete'),
diff --git a/mod/groups/views/default/groups/js.php b/mod/groups/views/default/groups/js.php
index 1b4d33f32..0319be14a 100644
--- a/mod/groups/views/default/groups/js.php
+++ b/mod/groups/views/default/groups/js.php
@@ -1,3 +1,10 @@
+<?php
+/**
+ * Javascript for Groups forms
+ *
+ * @package ElggGroups
+ */
+?>
// this adds a class to support IE8 and older
elgg.register_hook_handler('init', 'system', function() {
diff --git a/mod/groups/views/rss/groups/profile/layout.php b/mod/groups/views/rss/groups/profile/layout.php
index 3eeb9eaf2..0dafe78ad 100644
--- a/mod/groups/views/rss/groups/profile/layout.php
+++ b/mod/groups/views/rss/groups/profile/layout.php
@@ -7,7 +7,12 @@
* @uses $vars['entity'] ElggGroup object
*/
-echo elgg_list_entities(array(
- 'type' => 'object',
- 'container_guid' => $vars['entity']->getGUID(),
-));
+$entities = elgg_get_config('registered_entities');
+
+if (!empty($entities['object'])) {
+ echo elgg_list_entities(array(
+ 'type' => 'object',
+ 'subtypes' => $entities['object'],
+ 'container_guid' => $vars['entity']->getGUID(),
+ ));
+}
diff --git a/mod/groups/views/rss/object/groupforumtopic.php b/mod/groups/views/rss/object/groupforumtopic.php
index d730ef796..b2d05d488 100644
--- a/mod/groups/views/rss/object/groupforumtopic.php
+++ b/mod/groups/views/rss/object/groupforumtopic.php
@@ -14,7 +14,7 @@ if (empty($title)) {
$permalink = htmlspecialchars($vars['entity']->getURL(), ENT_NOQUOTES, 'UTF-8');
$pubdate = date('r', $vars['entity']->getTimeCreated());
-$description = autop($vars['entity']->description);
+$description = elgg_autop($vars['entity']->description);
$creator = elgg_view('page/components/creator', $vars);
$georss = elgg_view('page/components/georss', $vars);
diff --git a/mod/messageboard/views/default/river/object/messageboard/create.php b/mod/messageboard/views/default/river/object/messageboard/create.php
index 7ce7f6b4e..ac10a55c1 100644
--- a/mod/messageboard/views/default/river/object/messageboard/create.php
+++ b/mod/messageboard/views/default/river/object/messageboard/create.php
@@ -1,11 +1,12 @@
-<?php
-/**
- * Messageboard river view
- */
-
-$messageboard = $vars['item']->getAnnotation();
-
-echo elgg_view('river/elements/layout', array(
- 'item' => $vars['item'],
- 'message' => $messageboard->value,
-));
+<?php
+/**
+ * Messageboard river view
+ */
+
+$messageboard = $vars['item']->getAnnotation();
+$excerpt = elgg_get_excerpt($messageboard->value);
+
+echo elgg_view('river/elements/layout', array(
+ 'item' => $vars['item'],
+ 'message' => $excerpt,
+));
diff --git a/mod/messages/pages/messages/read.php b/mod/messages/pages/messages/read.php
index eb36eaa4b..4223c6bac 100644
--- a/mod/messages/pages/messages/read.php
+++ b/mod/messages/pages/messages/read.php
@@ -38,9 +38,9 @@ if ($inbox) {
);
$body_params = array('message' => $message);
$content .= elgg_view_form('messages/reply', $form_params, $body_params);
- $from_user = get_user($message->fromID);
+ $from_user = get_user($message->fromId);
- if (elgg_get_logged_in_user_guid() == elgg_get_page_owner_guid() && $from_user) {
+ if ((elgg_get_logged_in_user_guid() == elgg_get_page_owner_guid()) && $from_user) {
elgg_register_menu_item('title', array(
'name' => 'reply',
'href' => '#messages-reply-form',
diff --git a/mod/profile/icondirect.php b/mod/profile/icondirect.php
index c4439f78c..dbab5d31f 100644
--- a/mod/profile/icondirect.php
+++ b/mod/profile/icondirect.php
@@ -23,7 +23,7 @@ $guid = (int)$_GET['guid'];
// If is the same ETag, content didn't changed.
$etag = $last_cache . $guid;
-if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
+if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == "\"$etag\"") {
header("HTTP/1.1 304 Not Modified");
exit;
}
@@ -55,19 +55,15 @@ if ($mysql_dblink) {
$user_path = date('Y/m/d/', $join_date) . $guid;
$filename = "$data_root$user_path/profile/{$guid}{$size}.jpg";
- $contents = @file_get_contents($filename);
- if (!empty($contents)) {
+ $size = @filesize($filename);
+ if ($size) {
header("Content-type: image/jpeg");
- header('Expires: ' . date('r', strtotime("+6 months")), true);
+ header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
header("Pragma: public");
header("Cache-Control: public");
- header("Content-Length: " . strlen($contents));
- header("ETag: $etag");
- // this chunking is done for supposedly better performance
- $split_string = str_split($contents, 1024);
- foreach ($split_string as $chunk) {
- echo $chunk;
- }
+ header("Content-Length: $size");
+ header("ETag: \"$etag\"");
+ readfile($filename);
exit;
}
}
diff --git a/mod/profile/views/default/profile/details.php b/mod/profile/views/default/profile/details.php
index 3af5cb756..7b05b0e15 100644
--- a/mod/profile/views/default/profile/details.php
+++ b/mod/profile/views/default/profile/details.php
@@ -28,7 +28,7 @@ if (is_array($profile_fields) && sizeof($profile_fields) > 0) {
<div class="<?php echo $even_odd; ?>">
<b><?php echo elgg_echo("profile:{$shortname}"); ?>: </b>
<?php
- echo elgg_view("output/{$valtype}", array('value' => $user->$shortname));
+ echo elgg_view("output/{$valtype}", array('value' => $value));
?>
</div>
<?php
diff --git a/mod/search/views/default/search/no_results.php b/mod/search/views/default/search/no_results.php
index 74b5b2cfa..0e9a5e295 100644
--- a/mod/search/views/default/search/no_results.php
+++ b/mod/search/views/default/search/no_results.php
@@ -3,4 +3,4 @@
* No results from search
*/
-echo autop(elgg_echo('search:no_results'));
+echo elgg_autop(elgg_echo('search:no_results'));
diff --git a/mod/thewire/views/rss/object/thewire.php b/mod/thewire/views/rss/object/thewire.php
index 494c2c8dc..8fddb8aa8 100644
--- a/mod/thewire/views/rss/object/thewire.php
+++ b/mod/thewire/views/rss/object/thewire.php
@@ -15,7 +15,7 @@ $title = elgg_echo('thewire:by', array($owner->name));
$permalink = htmlspecialchars($vars['entity']->getURL(), ENT_NOQUOTES, 'UTF-8');
$pubdate = date('r', $vars['entity']->getTimeCreated());
-$description = autop($vars['entity']->description);
+$description = elgg_autop($vars['entity']->description);
$creator = elgg_view('page/components/creator', $vars);
$georss = elgg_view('page/components/georss', $vars);
diff --git a/mod/twitter/views/default/widgets/twitter/content.php b/mod/twitter/views/default/widgets/twitter/content.php
index e429d0103..c616d944c 100644
--- a/mod/twitter/views/default/widgets/twitter/content.php
+++ b/mod/twitter/views/default/widgets/twitter/content.php
@@ -20,7 +20,7 @@ if ($username) {
<ul id="twitter_update_list"></ul>
<p class="visit_twitter"><a href="http://twitter.com/<?php echo $username; ?>"><?php echo elgg_echo("twitter:visit"); ?></a></p>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
- <script type="text/javascript" src="http://twitter.com/statuses/user_timeline/<?php echo $username; ?>.json?callback=twitterCallback2&count=<?php echo $num; ?>"></script>
+ <script type="text/javascript" src="https://api.twitter.com/1/statuses/user_timeline/<?php echo $username; ?>.json?callback=twitterCallback2&count=<?php echo $num; ?>"></script>
</div>
<?php
diff --git a/mod/twitter_api/vendors/twitteroauth/OAuth.php b/mod/twitter_api/vendors/twitteroauth/OAuth.php
index b0e3cfd5e..e132a5bc8 100644
--- a/mod/twitter_api/vendors/twitteroauth/OAuth.php
+++ b/mod/twitter_api/vendors/twitteroauth/OAuth.php
@@ -78,6 +78,7 @@ class twitterOAuthRequest extends OAuthRequest {
private $http_url;
// for debug purposes
public $base_string;
+ public static $version = '1.0';
public static $POST_INPUT = 'php://input';
function __construct($http_method, $http_url, $parameters=NULL) {
@@ -145,7 +146,7 @@ class twitterOAuthRequest extends OAuthRequest {
*/
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
@$parameters or $parameters = array();
- $defaults = array("oauth_version" => '1.0',
+ $defaults = array("oauth_version" => twitterOAuthRequest::$version,
"oauth_nonce" => twitterOAuthRequest::generate_nonce(),
"oauth_timestamp" => twitterOAuthRequest::generate_timestamp(),
"oauth_consumer_key" => $consumer->key);
diff --git a/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php b/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php
index a1021ce6f..f36e6158d 100644
--- a/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php
+++ b/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php
@@ -43,8 +43,8 @@ class TwitterOAuth {
* Set API URLS
*/
function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; }
- function authenticateURL() { return 'https://twitter.com/oauth/authenticate'; }
- function authorizeURL() { return 'https://twitter.com/oauth/authorize'; }
+ function authenticateURL() { return 'https://api.twitter.com/oauth/authenticate'; }
+ function authorizeURL() { return 'https://api.twitter.com/oauth/authorize'; }
function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; }
/**
diff --git a/mod/uservalidationbyemail/start.php b/mod/uservalidationbyemail/start.php
index f98f57faf..f44d2ab50 100644
--- a/mod/uservalidationbyemail/start.php
+++ b/mod/uservalidationbyemail/start.php
@@ -233,15 +233,23 @@ function uservalidationbyemail_public_pages($hook, $type, $return_value, $params
* @param string $type
* @param ElggUser $user
* @return bool
+ *
+ * @throws LoginException
*/
function uservalidationbyemail_check_manual_login($event, $type, $user) {
$access_status = access_get_show_hidden_status();
access_show_hidden_entities(TRUE);
- // @todo register_error()?
- $return = ($user instanceof ElggUser && !$user->isEnabled() && !$user->validated) ? FALSE : NULL;
+ if (($user instanceof ElggUser) && !$user->isEnabled() && !$user->validated) {
+ // send new validation email
+ uservalidationbyemail_request_validation($user->getGUID());
+
+ // restore hidden entities settings
+ access_show_hidden_entities($access_status);
+
+ // throw error so we get a nice error message
+ throw new LoginException(elgg_echo('uservalidationbyemail:login:fail'));
+ }
access_show_hidden_entities($access_status);
-
- return $return;
}
diff --git a/mod/uservalidationbyemail/views/default/forms/uservalidationbyemail/bulk_action.php b/mod/uservalidationbyemail/views/default/forms/uservalidationbyemail/bulk_action.php
index cbd13a709..9199922d6 100644
--- a/mod/uservalidationbyemail/views/default/forms/uservalidationbyemail/bulk_action.php
+++ b/mod/uservalidationbyemail/views/default/forms/uservalidationbyemail/bulk_action.php
@@ -27,7 +27,7 @@ if (!$count) {
access_show_hidden_entities($hidden_entities);
elgg_set_ignore_access($ia);
- echo autop(elgg_echo('uservalidationbyemail:admin:no_unvalidated_users'));
+ echo elgg_autop(elgg_echo('uservalidationbyemail:admin:no_unvalidated_users'));
return TRUE;
}
diff --git a/pages/avatar/view.php b/pages/avatar/view.php
index bd6c95821..10d81fef1 100644
--- a/pages/avatar/view.php
+++ b/pages/avatar/view.php
@@ -46,7 +46,7 @@ if (!$success) {
}
header("Content-type: image/jpeg", true);
-header('Expires: ' . date('r', strtotime("+6 months")), true);
+header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
header("Pragma: public", true);
header("Cache-Control: public", true);
header("Content-Length: " . strlen($contents));
diff --git a/version.php b/version.php
index dda087c52..77d151bb6 100644
--- a/version.php
+++ b/version.php
@@ -11,7 +11,7 @@
// YYYYMMDD = Elgg Date
// XX = Interim incrementer
-$version = 2012071100;
+$version = 2012120500;
// Human-friendly version name
-$release = '1.8.8';
+$release = '1.8.11';
diff --git a/views/default/admin/users/admins.php b/views/default/admin/users/admins.php
new file mode 100644
index 000000000..9b175d437
--- /dev/null
+++ b/views/default/admin/users/admins.php
@@ -0,0 +1,12 @@
+<?php
+$admins = elgg_list_entities(array(), 'elgg_get_admins');
+
+?>
+<div class="elgg-module elgg-module-inline">
+ <div class="elgg-head">
+ <h3><?php echo elgg_echo('admin:statistics:label:admins'); ?></h3>
+ </div>
+ <div class="elgg-body">
+ <?php echo $admins; ?>
+ </div>
+</div>
diff --git a/views/default/css/admin.php b/views/default/css/admin.php
index b996e5636..059e51dd6 100644
--- a/views/default/css/admin.php
+++ b/views/default/css/admin.php
@@ -1238,6 +1238,10 @@ a.elgg-widget-collapsed:before {
height: 16px;
display: inline-block;
margin: 0 2px;
+ vertical-align: text-bottom;
+}
+.elgg-module .elgg-head .elgg-icon {
+ vertical-align: baseline;
}
.elgg-icon-delete:hover,
.elgg-icon-delete-alt:hover {
diff --git a/views/default/forms/profile/fields/add.php b/views/default/forms/profile/fields/add.php
index 1ea9c57a9..2087ec299 100644
--- a/views/default/forms/profile/fields/add.php
+++ b/views/default/forms/profile/fields/add.php
@@ -25,5 +25,5 @@ $formbody = <<< END
$submit_control</div>
END;
-echo autop(elgg_echo('profile:explainchangefields'));
+echo elgg_autop(elgg_echo('profile:explainchangefields'));
echo $formbody;
diff --git a/views/default/forms/user/passwordreset.php b/views/default/forms/user/passwordreset.php
index 3c89776f6..5946fa7c0 100644
--- a/views/default/forms/user/passwordreset.php
+++ b/views/default/forms/user/passwordreset.php
@@ -3,7 +3,7 @@
* Reset user password form
*/
-echo autop(elgg_echo('user:resetpassword:reset_password_confirm'));
+echo elgg_autop(elgg_echo('user:resetpassword:reset_password_confirm'));
echo elgg_view('input/hidden', array(
'name' => 'u',
diff --git a/views/default/js/admin.php b/views/default/js/admin.php
index 5cefba512..e8aa0d2ed 100644
--- a/views/default/js/admin.php
+++ b/views/default/js/admin.php
@@ -4,8 +4,9 @@
*
* @since 1.8
*/
+
+if (0) { ?><script><?php }
?>
-//<script>
elgg.provide('elgg.admin');
elgg.admin.init = function () {
@@ -47,7 +48,7 @@ elgg.admin.init = function () {
// admin notices delete ajax
$('a.elgg-admin-notice').click(elgg.admin.deleteNotice);
-}
+};
/**
* Save the plugin order after a move event.
@@ -88,7 +89,7 @@ elgg.admin.editProfileField = function(value, settings) {
elgg.action('profile/fields/edit', data);
return value;
-}
+};
/**
* Save the plugin profile order after a move event.
@@ -104,7 +105,7 @@ elgg.admin.moveProfileField = function(e, ui) {
elgg.action('profile/fields/reorder', {
fieldorder: orderStr
});
-}
+};
/**
* Fires the ajax action to delete the admin notice then hides the notice.
@@ -120,6 +121,6 @@ elgg.admin.deleteNotice = function(e) {
$container.slideUp('medium');
}
});
-}
+};
elgg.register_hook_handler('init', 'system', elgg.admin.init, 1000); \ No newline at end of file
diff --git a/views/default/js/elgg.php b/views/default/js/elgg.php
index 6460e93d6..b82d98ce4 100644
--- a/views/default/js/elgg.php
+++ b/views/default/js/elgg.php
@@ -50,6 +50,7 @@ foreach ($libs as $file) {
/**
* Set some values that are cacheable
*/
+if (0) { ?><script><?php }
?>
elgg.version = '<?php echo get_version(); ?>';
diff --git a/views/default/js/initialize_elgg.php b/views/default/js/initialize_elgg.php
index f8234f84f..b45c33463 100644
--- a/views/default/js/initialize_elgg.php
+++ b/views/default/js/initialize_elgg.php
@@ -3,6 +3,7 @@
* Initialize Elgg's js lib with the uncacheable data
*/
+if (0) { ?><script><?php }
?>
/**
* Don't want to cache these -- they could change for every request
diff --git a/views/default/js/lightbox.php b/views/default/js/lightbox.php
index c45d46098..d2bceaf90 100644
--- a/views/default/js/lightbox.php
+++ b/views/default/js/lightbox.php
@@ -16,6 +16,7 @@
* @todo add support for passing options: $('#myplugin-lightbox').elgg.ui.lightbox(options);
*/
+if (0) { ?><script><?php }
?>
/**
diff --git a/views/default/js/walled_garden.php b/views/default/js/walled_garden.php
index 13ec83c04..7a482fe23 100644
--- a/views/default/js/walled_garden.php
+++ b/views/default/js/walled_garden.php
@@ -12,6 +12,7 @@ $cancel_button = elgg_view('input/button', array(
));
$cancel_button = trim($cancel_button);
+if (0) { ?><script><?php }
?>
elgg.provide('elgg.walled_garden');
@@ -47,10 +48,10 @@ elgg.walled_garden.load = function(view) {
$(id).find('input.elgg-button-submit').after('<?php echo $cancel_button; ?>');
$('#elgg-walledgarden-login').fadeToggle();
$(id).fadeToggle();
- },
+ }
});
event.preventDefault();
- };
+ };
};
elgg.register_hook_handler('init', 'system', elgg.walled_garden.init); \ No newline at end of file
diff --git a/views/default/output/email.php b/views/default/output/email.php
index 00eefad1f..f5a8bc4b8 100644
--- a/views/default/output/email.php
+++ b/views/default/output/email.php
@@ -10,6 +10,8 @@
*
*/
+$encoded_value = htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8');
+
if (!empty($vars['value'])) {
- echo "<a href=\"mailto:" . $vars['value'] . "\">". htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8', false) ."</a>";
+ echo "<a href=\"mailto:$encoded_value\">$encoded_value</a>";
} \ No newline at end of file
diff --git a/views/default/output/longtext.php b/views/default/output/longtext.php
index 200f27de5..589100c4f 100644
--- a/views/default/output/longtext.php
+++ b/views/default/output/longtext.php
@@ -31,7 +31,7 @@ if ($parse_urls) {
$text = filter_tags($text);
-$text = autop($text);
+$text = elgg_autop($text);
$attributes = elgg_format_attributes($vars);
diff --git a/views/default/page/elements/messages.php b/views/default/page/elements/messages.php
index a35a48586..edd40d71e 100644
--- a/views/default/page/elements/messages.php
+++ b/views/default/page/elements/messages.php
@@ -18,7 +18,7 @@ if (isset($vars['object']) && is_array($vars['object']) && sizeof($vars['object'
foreach ($vars['object'] as $type => $list ) {
foreach ($list as $message) {
echo "<li class=\"elgg-message elgg-state-$type\">";
- echo autop($message);
+ echo elgg_autop($message);
echo '</li>';
}
}
diff --git a/views/installation/install/pages/admin.php b/views/installation/install/pages/admin.php
index 9456e682f..e810aa701 100644
--- a/views/installation/install/pages/admin.php
+++ b/views/installation/install/pages/admin.php
@@ -3,7 +3,7 @@
* Install create admin account page
*/
-echo autop(elgg_echo('install:admin:instructions'));
+echo elgg_autop(elgg_echo('install:admin:instructions'));
$vars['type'] = 'admin';
diff --git a/views/installation/install/pages/complete.php b/views/installation/install/pages/complete.php
index 2f5a04854..80f8e7434 100644
--- a/views/installation/install/pages/complete.php
+++ b/views/installation/install/pages/complete.php
@@ -3,7 +3,7 @@
* Install completion page
*/
-echo autop(elgg_echo('install:complete:instructions'));
+echo elgg_autop(elgg_echo('install:complete:instructions'));
?>
diff --git a/views/installation/install/pages/database.php b/views/installation/install/pages/database.php
index d3011c9e3..d24b4f57b 100644
--- a/views/installation/install/pages/database.php
+++ b/views/installation/install/pages/database.php
@@ -6,12 +6,12 @@
*/
if (isset($vars['failure']) && $vars['failure']) {
- echo autop(elgg_echo('install:database:error'));
+ echo elgg_autop(elgg_echo('install:database:error'));
$vars['refresh'] = TRUE;
$vars['advance'] = FALSE;
echo elgg_view('install/nav', $vars);
} else {
- echo autop(elgg_echo('install:database:instructions'));
+ echo elgg_autop(elgg_echo('install:database:instructions'));
$vars['type'] = 'database';
diff --git a/views/installation/install/pages/requirements.php b/views/installation/install/pages/requirements.php
index e3689e761..06f309c90 100644
--- a/views/installation/install/pages/requirements.php
+++ b/views/installation/install/pages/requirements.php
@@ -14,7 +14,7 @@ if ($vars['num_failures'] != 0) {
$instruct_text = elgg_echo('install:requirements:instructions:success');
}
-echo autop($instruct_text);
+echo elgg_autop($instruct_text);
$report = $vars['report'];
foreach ($report as $category => $checks) {
@@ -23,7 +23,7 @@ foreach ($report as $category => $checks) {
echo "<ul class=\"elgg-require-$category\">";
foreach ($checks as $check) {
echo "<li class=\"{$check['severity']}\">";
- echo autop($check['message']);
+ echo elgg_autop($check['message']);
echo "</li>";
}
echo "</ul>";
diff --git a/views/installation/install/pages/settings.php b/views/installation/install/pages/settings.php
index 30a1deb5a..04f23c0ea 100644
--- a/views/installation/install/pages/settings.php
+++ b/views/installation/install/pages/settings.php
@@ -1,6 +1,6 @@
<?php
-echo autop(elgg_echo('install:settings:instructions'));
+echo elgg_autop(elgg_echo('install:settings:instructions'));
$vars['type'] = 'settings';
diff --git a/views/installation/install/pages/welcome.php b/views/installation/install/pages/welcome.php
index f069e4ba7..f370c15f3 100644
--- a/views/installation/install/pages/welcome.php
+++ b/views/installation/install/pages/welcome.php
@@ -3,6 +3,6 @@
* Install welcome page
*/
-echo autop(elgg_echo('install:welcome:instructions'));
+echo elgg_autop(elgg_echo('install:welcome:instructions'));
echo elgg_view('install/nav', $vars);
diff --git a/views/installation/page/elements/messages.php b/views/installation/page/elements/messages.php
index 2a06a7b1e..46261dca4 100644
--- a/views/installation/page/elements/messages.php
+++ b/views/installation/page/elements/messages.php
@@ -12,7 +12,7 @@ if (isset($vars['object']) && is_array($vars['object']) && sizeof($vars['object'
foreach ($vars['object'] as $type => $list ) {
foreach ($list as $message) {
echo "<li class=\"elgg-state-$type\">";
- echo autop($message);
+ echo elgg_autop($message);
echo '</li>';
}
}
diff --git a/views/opendd/messages/exceptions/exception.php b/views/opendd/messages/exceptions/exception.php
index 54868f1f4..dc0f48a8d 100644
--- a/views/opendd/messages/exceptions/exception.php
+++ b/views/opendd/messages/exceptions/exception.php
@@ -11,7 +11,7 @@
?>
<!--
-<?php echo get_class($vars['object']); ?>: <?php echo autop($vars['object']->getMessage()); ?>
+<?php echo get_class($vars['object']); ?>: <?php echo elgg_autop($vars['object']->getMessage()); ?>
<?php if (elgg_get_config('debug')) { ?>
<?php
echo print_r($vars['object'], true);
diff --git a/views/rss/group/default.php b/views/rss/group/default.php
index f57c7f82c..7fef4d434 100644
--- a/views/rss/group/default.php
+++ b/views/rss/group/default.php
@@ -11,9 +11,9 @@ $pubdate = date('r', $vars['entity']->getTimeCreated());
$title = htmlspecialchars($vars['entity']->name, ENT_NOQUOTES, 'UTF-8');
if ($vars['entity']->description) {
- $description = autop($vars['entity']->description);
+ $description = elgg_autop($vars['entity']->description);
} elseif ($vars['entity']->briefdescription) {
- $description = autop($vars['entity']->briefdescription);
+ $description = elgg_autop($vars['entity']->briefdescription);
} else {
$description = '';
}
diff --git a/views/rss/object/default.php b/views/rss/object/default.php
index be8025953..8c7d5d8e0 100644
--- a/views/rss/object/default.php
+++ b/views/rss/object/default.php
@@ -15,7 +15,7 @@ if (empty($title)) {
$permalink = htmlspecialchars($vars['entity']->getURL(), ENT_NOQUOTES, 'UTF-8');
$pubdate = date('r', $vars['entity']->getTimeCreated());
-$description = autop($vars['entity']->description);
+$description = elgg_autop($vars['entity']->description);
$creator = elgg_view('page/components/creator', $vars);
$georss = elgg_view('page/components/georss', $vars);
diff --git a/views/rss/user/default.php b/views/rss/user/default.php
index 1c7bf75e7..92c9427b2 100644
--- a/views/rss/user/default.php
+++ b/views/rss/user/default.php
@@ -11,7 +11,7 @@ $pubdate = date('r', $vars['entity']->getTimeCreated());
$title = htmlspecialchars($vars['entity']->name, ENT_NOQUOTES, 'UTF-8');
if ($vars['entity']->description) {
- $description = autop($vars['entity']->description);
+ $description = elgg_autop($vars['entity']->description);
} else {
$description = '';
}
diff --git a/views/xml/messages/exceptions/exception.php b/views/xml/messages/exceptions/exception.php
index 3e4e1c376..66a0f2b96 100644
--- a/views/xml/messages/exceptions/exception.php
+++ b/views/xml/messages/exceptions/exception.php
@@ -11,7 +11,7 @@
?>
<!--
-<?php echo get_class($vars['object']); ?>: <?php echo autop($vars['object']->getMessage()); ?>
+<?php echo get_class($vars['object']); ?>: <?php echo elgg_autop($vars['object']->getMessage()); ?>
<?php if (elgg_get_config('debug')) { ?>