diff options
265 files changed, 7311 insertions, 960 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index b502b8411..ca1bdc675 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,125 @@ +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) + + Contributing Developers: + * Cash Costello + * Miguel Rodriguez + * Sem + + Enhancements: + * Added a delete button on river items for admins + + Bugfixes: + * Fixed the significant bug with htmlawed plugin that caused duplicate tags + + +Version 1.8.7 +(July 10, 2012 from https://github.com/Elgg/Elgg/tree/1.8) + + Contributing Developers: + * Cash Costello + * Evan Winslow + * Ismayil Khayredinov + * Jeroen Dalsem + * Jerome Bakker + * Matt Beckett + * Miguel Rodriguez + * Paweł Sroka + * Sem + * Steve Clay + + Enhancements: + * Better support for search engine friendly URLs + * Upgraded htmlawed (XSS filtering) + * Internationalization support for TinyMCE + * Public access not available for walled gardens + * Better forwarding and messages when they cannot view content because logged out + + Bugfixes: + * Fatal errors due to type hints downgraded to warnings + * Group discussion reply notifications work again + * Sending user to inbox when deleting a message + * Fixed location profile information when it is an array + * Over 30 other bug fixes. + + Version 1.8.6 (June 18, 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/admin/plugins/activate.php b/actions/admin/plugins/activate.php index 286cf5a4f..5234a4ca5 100644 --- a/actions/admin/plugins/activate.php +++ b/actions/admin/plugins/activate.php @@ -47,7 +47,8 @@ if (count($activated_guids) === 1) { $url .= "?$query"; } $plugin = get_entity($plugin_guids[0]); - forward("$url#{$plugin->getID()}"); + $id = $css_id = preg_replace('/[^a-z0-9-]/i', '-', $plugin->getID()); + forward("$url#$id"); } else { // forward to top of page with a failure so remove any #foo $url = $_SERVER['HTTP_REFERER']; diff --git a/actions/admin/plugins/deactivate.php b/actions/admin/plugins/deactivate.php index e7ce65625..354f4717d 100644 --- a/actions/admin/plugins/deactivate.php +++ b/actions/admin/plugins/deactivate.php @@ -46,7 +46,8 @@ if (count($plugin_guids) == 1) { $url .= "?$query"; } $plugin = get_entity($plugin_guids[0]); - forward("$url#{$plugin->getID()}"); + $id = preg_replace('/[^a-z0-9-]/i', '-', $plugin->getID()); + forward("$url#$id"); } else { forward(REFERER); } diff --git a/actions/admin/site/update_advanced.php b/actions/admin/site/update_advanced.php index 897a2f983..0fd8d1f35 100644 --- a/actions/admin/site/update_advanced.php +++ b/actions/admin/site/update_advanced.php @@ -53,8 +53,6 @@ if ($site = elgg_get_site_entity()) { $user_default_access = (get_input('allow_user_default_access')) ? 1 : 0; set_config('allow_user_default_access', $user_default_access, $site->getGUID()); - set_config('view', get_input('view'), $site->getGUID()); - $debug = get_input('debug'); if ($debug) { set_config('debug', $debug, $site->getGUID()); diff --git a/actions/plugins/settings/save.php b/actions/plugins/settings/save.php index e94127f7c..581a2f9ec 100644 --- a/actions/plugins/settings/save.php +++ b/actions/plugins/settings/save.php @@ -3,7 +3,7 @@ * Saves global plugin settings. * * This action can be overriden for a specific plugin by creating the - * settings/<plugin_id>/save action in that plugin. + * <plugin_id>/settings/save action in that plugin. * * @uses array $_REQUEST['params'] A set of key/value pairs to save to the ElggPlugin entity * @uses int $_REQUEST['plugin_id'] The ID of the plugin diff --git a/actions/plugins/usersettings/save.php b/actions/plugins/usersettings/save.php index 71ad2ad7b..f6b8ab0b6 100644 --- a/actions/plugins/usersettings/save.php +++ b/actions/plugins/usersettings/save.php @@ -3,7 +3,7 @@ * Saves user-specific plugin settings. * * This action can be overriden for a specific plugin by creating the - * settings/<plugin_id>/save action in that plugin. + * <plugin_id>/usersettings/save action in that plugin. * * @uses array $_REQUEST['params'] A set of key/value pairs to save to the ElggPlugin entity * @uses int $_REQUEST['plugin_id'] The id of the plugin diff --git a/actions/profile/edit.php b/actions/profile/edit.php index 8ca60f246..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 @@ -51,7 +51,7 @@ foreach ($profile_fields as $shortname => $valuetype) { if ($valuetype == 'tags') { $value = string_to_tag_array($value); } - + $input[$shortname] = $value; } @@ -71,24 +71,30 @@ if (sizeof($input) > 0) { foreach ($input as $shortname => $value) { $options = array( 'guid' => $owner->guid, - 'metadata_name' => $shortname + 'metadata_name' => $shortname, + 'limit' => false ); elgg_delete_metadata($options); - if (isset($accesslevel[$shortname])) { - $access_id = (int) $accesslevel[$shortname]; - } else { - // this should never be executed since the access level should always be set - $access_id = ACCESS_DEFAULT; - } - if (is_array($value)) { - $i = 0; - foreach ($value as $interval) { - $i++; - $multiple = ($i > 1) ? TRUE : FALSE; - create_metadata($owner->guid, $shortname, $interval, 'text', $owner->guid, $access_id, $multiple); + + if(!is_null($value) && ($value !== '')){ + // only create metadata for non empty values (0 is allowed) to prevent metadata records with empty string values #4858 + + if (isset($accesslevel[$shortname])) { + $access_id = (int) $accesslevel[$shortname]; + } else { + // this should never be executed since the access level should always be set + $access_id = ACCESS_DEFAULT; + } + if (is_array($value)) { + $i = 0; + foreach ($value as $interval) { + $i++; + $multiple = ($i > 1) ? TRUE : FALSE; + create_metadata($owner->guid, $shortname, $interval, 'text', $owner->guid, $access_id, $multiple); + } + } else { + create_metadata($owner->getGUID(), $shortname, $value, 'text', $owner->getGUID(), $access_id); } - } else { - create_metadata($owner->getGUID(), $shortname, $value, 'text', $owner->getGUID(), $access_id); } } 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/actions/river/delete.php b/actions/river/delete.php new file mode 100644 index 000000000..0d8297932 --- /dev/null +++ b/actions/river/delete.php @@ -0,0 +1,21 @@ +<?php +/** + * River item delete action + * + * @package Elgg + * @subpackage Core + */ + +$id = get_input('id', false); + +if ($id !== false && elgg_is_admin_logged_in()) { + if (elgg_delete_river(array('id' => $id))) { + system_message(elgg_echo('river:delete:success')); + } else { + register_error(elgg_echo('river:delete:fail')); + } +} else { + register_error(elgg_echo('river:delete:fail')); +} + +forward(REFERER); diff --git a/actions/widgets/add.php b/actions/widgets/add.php index f65d11134..d7b2f291c 100644 --- a/actions/widgets/add.php +++ b/actions/widgets/add.php @@ -9,6 +9,7 @@ $owner_guid = get_input('owner_guid'); $handler = get_input('handler'); $context = get_input('context'); +$show_access = (bool)get_input('show_access', true); $column = get_input('column', 1); $default_widgets = get_input('default_widgets', 0); @@ -29,7 +30,7 @@ if (!empty($owner_guid)) { $widget->move($column, 0); // send widget html for insertion - echo elgg_view_entity($widget); + echo elgg_view_entity($widget, array('show_access' => $show_access)); //system_message(elgg_echo('widgets:add:success')); forward(REFERER); diff --git a/documentation/info/manifest.xml b/documentation/info/manifest.xml index baa6cc3fa..494158481 100644 --- a/documentation/info/manifest.xml +++ b/documentation/info/manifest.xml @@ -6,6 +6,9 @@ <blurb>A concise description.</blurb> <description>This is a longer, more interesting description of my plugin, its features, and other important information.</description> <website>http://www.elgg.org/</website> + <repository>https://github.com/Elgg/Elgg</repository> + <bugtracker>http://trac.elgg.org</bugtracker> + <donations>http://elgg.org/supporter.php</donations> <copyright>(C) Elgg 2011</copyright> <license>GNU General Public License version 2</license> 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/ElggEntity.php b/engine/classes/ElggEntity.php index 77c2bbf4d..929abceb2 100644 --- a/engine/classes/ElggEntity.php +++ b/engine/classes/ElggEntity.php @@ -248,7 +248,9 @@ abstract class ElggEntity extends ElggData implements * @return mixed The value, or NULL if not found. */ public function getMetaData($name) { - if ((int) ($this->guid) == 0) { + $guid = $this->getGUID(); + + if (! $guid) { if (isset($this->temp_metadata[$name])) { // md is returned as an array only if more than 1 entry if (count($this->temp_metadata[$name]) == 1) { @@ -261,21 +263,38 @@ abstract class ElggEntity extends ElggData implements } } + // upon first cache miss, just load/cache all the metadata and retry. + // if this works, the rest of this function may not be needed! + $cache = elgg_get_metadata_cache(); + if ($cache->isKnown($guid, $name)) { + return $cache->load($guid, $name); + } else { + $cache->populateFromEntities(array($guid)); + // in case ignore_access was on, we have to check again... + if ($cache->isKnown($guid, $name)) { + return $cache->load($guid, $name); + } + } + $md = elgg_get_metadata(array( - 'guid' => $this->getGUID(), + 'guid' => $guid, 'metadata_name' => $name, 'limit' => 0, )); + $value = null; + if ($md && !is_array($md)) { - return $md->value; + $value = $md->value; } elseif (count($md) == 1) { - return $md[0]->value; + $value = $md[0]->value; } else if ($md && is_array($md)) { - return metadata_array_to_values($md); + $value = metadata_array_to_values($md); } - return null; + $cache->save($guid, $name, $value); + + return $value; } /** @@ -1007,7 +1026,7 @@ abstract class ElggEntity extends ElggData implements /** * Returns the guid. * - * @return int GUID + * @return int|null GUID */ public function getGUID() { return $this->get('guid'); @@ -1245,16 +1264,16 @@ abstract class ElggEntity extends ElggData implements /** * Save an entity. * - * @return bool/int + * @return bool|int * @throws IOException */ public function save() { - $guid = (int) $this->guid; + $guid = $this->getGUID(); if ($guid > 0) { cache_entity($this); return update_entity( - $this->get('guid'), + $guid, $this->get('owner_guid'), $this->get('access_id'), $this->get('container_guid'), @@ -1301,10 +1320,7 @@ abstract class ElggEntity extends ElggData implements $this->attributes['subtype'] = get_subtype_id($this->attributes['type'], $this->attributes['subtype']); - // Cache object handle - if ($this->attributes['guid']) { - cache_entity($this); - } + cache_entity($this); return $this->attributes['guid']; } diff --git a/engine/classes/ElggMenuBuilder.php b/engine/classes/ElggMenuBuilder.php index de0017599..df0f9147f 100644 --- a/engine/classes/ElggMenuBuilder.php +++ b/engine/classes/ElggMenuBuilder.php @@ -204,6 +204,9 @@ class ElggMenuBuilder { // sort each section foreach ($this->menu as $index => $section) { + foreach ($section as $key => $node) { + $section[$key]->original_order = $key; + } usort($section, $sort_callback); $this->menu[$index] = $section; @@ -232,10 +235,14 @@ class ElggMenuBuilder { * @return bool */ public static function compareByText($a, $b) { - $a = $a->getText(); - $b = $b->getText(); + $at = $a->getText(); + $bt = $b->getText(); - return strnatcmp($a, $b); + $result = strnatcmp($at, $bt); + if ($result === 0) { + return $a->original_order - $b->original_order; + } + return $result; } /** @@ -246,10 +253,14 @@ class ElggMenuBuilder { * @return bool */ public static function compareByName($a, $b) { - $a = $a->getName(); - $b = $b->getName(); + $an = $a->getName(); + $bn = $b->getName(); - return strcmp($a, $b); + $result = strcmp($an, $bn); + if ($result === 0) { + return $a->original_order - $b->original_order; + } + return $result; } /** @@ -260,9 +271,12 @@ class ElggMenuBuilder { * @return bool */ public static function compareByWeight($a, $b) { - $a = $a->getWeight(); - $b = $b->getWeight(); + $aw = $a->getWeight(); + $bw = $b->getWeight(); - return $a > $b; + if ($aw == $bw) { + return $a->original_order - $b->original_order; + } + return $aw - $bw; } } diff --git a/engine/classes/ElggMenuItem.php b/engine/classes/ElggMenuItem.php index 4bc9144d4..fe25f3ddd 100644 --- a/engine/classes/ElggMenuItem.php +++ b/engine/classes/ElggMenuItem.php @@ -542,6 +542,9 @@ class ElggMenuItem { * @return void */ public function sortChildren($sortFunction) { + foreach ($this->data['children'] as $key => $node) { + $this->data['children'][$key]->original_order = $key; + } usort($this->data['children'], $sortFunction); } diff --git a/engine/classes/ElggMetadata.php b/engine/classes/ElggMetadata.php index 634a122e5..7f45dc3ea 100644 --- a/engine/classes/ElggMetadata.php +++ b/engine/classes/ElggMetadata.php @@ -26,8 +26,6 @@ class ElggMetadata extends ElggExtender { * Construct a metadata object * * @param mixed $id ID of metadata or a database row as stdClass object - * - * @return void */ function __construct($id = null) { $this->initializeAttributes(); @@ -54,7 +52,7 @@ class ElggMetadata extends ElggExtender { * * @param int $user_guid The GUID of the user (defaults to currently logged in user) * - * @return true|false Depending on permissions + * @return bool Depending on permissions */ function canEdit($user_guid = 0) { if ($entity = get_entity($this->get('entity_guid'))) { @@ -64,9 +62,11 @@ class ElggMetadata extends ElggExtender { } /** - * Save matadata object + * Save metadata object * - * @return int the metadata object id + * @return int|bool the metadata object id or true if updated + * + * @throws IOException */ function save() { if ($this->id > 0) { @@ -89,7 +89,13 @@ class ElggMetadata extends ElggExtender { * @return bool */ function delete() { - return elgg_delete_metastring_based_object_by_id($this->id, 'metadata'); + $success = elgg_delete_metastring_based_object_by_id($this->id, 'metadata'); + if ($success) { + // we mark unknown here because this deletes only one value + // under this name, and there may be others remaining. + elgg_get_metadata_cache()->markUnknown($this->entity_guid, $this->name); + } + return $success; } /** @@ -99,17 +105,27 @@ class ElggMetadata extends ElggExtender { * @since 1.8 */ function disable() { - return elgg_set_metastring_based_object_enabled_by_id($this->id, 'no', 'metadata'); + $success = elgg_set_metastring_based_object_enabled_by_id($this->id, 'no', 'metadata'); + if ($success) { + // we mark unknown here because this disables only one value + // under this name, and there may be others remaining. + elgg_get_metadata_cache()->markUnknown($this->entity_guid, $this->name); + } + return $success; } /** - * Disable the metadata + * Enable the metadata * * @return bool * @since 1.8 */ function enable() { - return elgg_set_metastring_based_object_enabled_by_id($this->id, 'yes', 'metadata'); + $success = elgg_set_metastring_based_object_enabled_by_id($this->id, 'yes', 'metadata'); + if ($success) { + elgg_get_metadata_cache()->markUnknown($this->entity_guid, $this->name); + } + return $success; } /** diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php index b4bae6825..fa6296c8c 100644 --- a/engine/classes/ElggObject.php +++ b/engine/classes/ElggObject.php @@ -223,7 +223,7 @@ class ElggObject extends ElggEntity { // must be member of group if (elgg_instanceof($this->getContainerEntity(), 'group')) { - if (!$this->getContainerEntity()->canWriteToContainer(get_user($user_guid))) { + if (!$this->getContainerEntity()->canWriteToContainer($user_guid)) { return false; } } 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 8c9093834..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); } /** @@ -101,7 +104,6 @@ class ElggPlugin extends ElggObject { $missing_attributes = array_diff_key($expected_attributes, $row); if ($missing_attributes) { $needs_loaded = true; - $old_guid = $guid; $guid = $row['guid']; } else { $this->attributes = $row; @@ -132,10 +134,7 @@ class ElggPlugin extends ElggObject { // guid needs to be an int http://trac.elgg.org/ticket/4111 $this->attributes['guid'] = (int)$this->attributes['guid']; - // cache the entity - if ($this->attributes['guid']) { - cache_entity($this); - } + cache_entity($this); return true; } diff --git a/engine/classes/ElggPluginManifest.php b/engine/classes/ElggPluginManifest.php index 7e79c15c8..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) == '<') { @@ -264,7 +264,7 @@ class ElggPluginManifest { /** * Returns the license * - * @return sting + * @return string */ public function getLicense() { // license vs licence. Use license. @@ -276,6 +276,32 @@ class ElggPluginManifest { } } + /** + * Returns the repository url + * + * @return string + */ + public function getRepositoryURL() { + return $this->parser->getAttribute('repository'); + } + + /** + * Returns the bug tracker page + * + * @return string + */ + public function getBugTrackerURL() { + return $this->parser->getAttribute('bugtracker'); + } + + /** + * Returns the donations page + * + * @return string + */ + public function getDonationsPageURL() { + return $this->parser->getAttribute('donations'); + } /** * Returns the version of the plugin. @@ -456,7 +482,7 @@ class ElggPluginManifest { * Normalizes a dependency array using the defined structs. * Can be used with either requires or suggests. * - * @param array $dep An dependency array. + * @param array $dep A dependency array. * @return array The normalized deps array. */ private function normalizeDep($dep) { @@ -500,8 +526,10 @@ class ElggPluginManifest { break; } } - break; + default: + // unrecognized so we just return the raw dependency + return $dep; } $normalized_dep = $this->buildStruct($struct, $dep); diff --git a/engine/classes/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/ElggPluginManifestParser18.php b/engine/classes/ElggPluginManifestParser18.php index 554e28c02..3b753f17b 100644 --- a/engine/classes/ElggPluginManifestParser18.php +++ b/engine/classes/ElggPluginManifestParser18.php @@ -13,10 +13,10 @@ class ElggPluginManifestParser18 extends ElggPluginManifestParser { * @var array */ protected $validAttributes = array( - 'name', 'author', 'version', 'blurb', 'description', - 'website', 'copyright', 'license', 'requires', 'suggests', - 'screenshot', 'category', 'conflicts', 'provides', - 'activate_on_install' + 'name', 'author', 'version', 'blurb', 'description','website', + 'repository', 'bugtracker', 'donations', 'copyright', 'license', + 'requires', 'suggests', 'conflicts', 'provides', + 'screenshot', 'category', 'activate_on_install' ); /** @@ -46,6 +46,9 @@ class ElggPluginManifestParser18 extends ElggPluginManifestParser { case 'website': case 'copyright': case 'license': + case 'repository': + case 'bugtracker': + case 'donations': case 'activate_on_install': $parsed[$element->name] = $element->content; break; diff --git a/engine/classes/ElggTranslit.php b/engine/classes/ElggTranslit.php new file mode 100644 index 000000000..676c59fc8 --- /dev/null +++ b/engine/classes/ElggTranslit.php @@ -0,0 +1,262 @@ +<?php +/** + * Elgg Transliterate + * + * For creating "friendly titles" for URLs + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This software consists of voluntary contributions made by many individuals + * and is licensed under the LGPL. For more information, see + * <http://www.doctrine-project.org>. + * + * @author Konsta Vesterinen <kvesteri@cc.hut.fi> + * @author Jonathan H. Wage <jonwage@gmail.com> + * + * @author Steve Clay <steve@mrclay.org> + * @package Elgg.Core + * + * @access private Plugin authors should not use this directly + */ +class ElggTranslit { + + /** + * Create a version of a string for embedding in a URL + * @param string $string a UTF-8 string + * @param string $separator + * @return string + */ + static public function urlize($string, $separator = '-') { + // Iñtërnâtiônàlizætiøn, AND 日本語! + + // try to force combined chars because the translit map and others expect it + if (self::hasNormalizerSupport()) { + $nfc = normalizer_normalize($string); + if (is_string($nfc)) { + $string = $nfc; + } + } + // Internationalization, AND 日本語! + $string = self::transliterateAscii($string); + + // more translation + $string = strtr($string, array( + // Euro/GBP + "\xE2\x82\xAC" /* € */ => 'E', "\xC2\xA3" /* £ */ => 'GBP', + )); + + // remove all ASCII except 0-9a-zA-Z, hyphen, underscore, and whitespace + // note: "x" modifier did not work with this pattern. + $string = preg_replace('~[' + . '\x00-\x08' # control chars + . '\x0b\x0c' # vert tab, form feed + . '\x0e-\x1f' # control chars + . '\x21-\x2c' # ! ... , + . '\x2e\x2f' # . slash + . '\x3a-\x40' # : ... @ + . '\x5b-\x5e' # [ ... ^ + . '\x60' # ` + . '\x7b-\x7f' # { ... DEL + . ']~', '', $string); + $string = strtr($string, '', ''); + + // internationalization, and 日本語! + // note: not using elgg_strtolower to keep this class portable + $string = is_callable('mb_strtolower') + ? mb_strtolower($string, 'UTF-8') + : strtolower($string); + + // split by ASCII chars not in 0-9a-zA-Z + // note: we cannot use [^0-9a-zA-Z] because that matches multibyte chars. + // note: "x" modifier did not work with this pattern. + $pattern = '~[' + . '\x00-\x2f' # controls ... slash + . '\x3a-\x40' # : ... @ + . '\x5b-\x60' # [ ... ` + . '\x7b-\x7f' # { ... DEL + . ']+~x'; + + // ['internationalization', 'and', '日本語'] + $words = preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY); + + // ['internationalization', 'and', '%E6%97%A5%E6%9C%AC%E8%AA%9E'] + $words = array_map('urlencode', $words); + + // internationalization-and-%E6%97%A5%E6%9C%AC%E8%AA%9E + return implode($separator, $words); + } + + /** + * Transliterate Western multibyte chars to ASCII + * @param string $utf8 a UTF-8 string + * @return string + */ + static public function transliterateAscii($utf8) { + static $map = null; + if (!preg_match('/[\x80-\xff]/', $utf8)) { + return $utf8; + } + if (null === $map) { + $map = self::getAsciiTranslitMap(); + } + return strtr($utf8, $map); + } + + /** + * Get array of UTF-8 (NFC) character replacements. + * + * @return array + */ + static public function getAsciiTranslitMap() { + return array( + // Decompositions for Latin-1 Supplement + "\xC2\xAA" /* ª */ => 'a', "\xC2\xBA" /* º */ => 'o', "\xC3\x80" /* À */ => 'A', + "\xC3\x81" /* Á */ => 'A', "\xC3\x82" /*  */ => 'A', "\xC3\x83" /* à */ => 'A', + "\xC3\x84" /* Ä */ => 'A', "\xC3\x85" /* Å */ => 'A', "\xC3\x86" /* Æ */ => 'AE', + "\xC3\x87" /* Ç */ => 'C', "\xC3\x88" /* È */ => 'E', "\xC3\x89" /* É */ => 'E', + "\xC3\x8A" /* Ê */ => 'E', "\xC3\x8B" /* Ë */ => 'E', "\xC3\x8C" /* Ì */ => 'I', + "\xC3\x8D" /* Í */ => 'I', "\xC3\x8E" /* Î */ => 'I', "\xC3\x8F" /* Ï */ => 'I', + "\xC3\x90" /* Ð */ => 'D', "\xC3\x91" /* Ñ */ => 'N', "\xC3\x92" /* Ò */ => 'O', + "\xC3\x93" /* Ó */ => 'O', "\xC3\x94" /* Ô */ => 'O', "\xC3\x95" /* Õ */ => 'O', + "\xC3\x96" /* Ö */ => 'O', "\xC3\x99" /* Ù */ => 'U', "\xC3\x9A" /* Ú */ => 'U', + "\xC3\x9B" /* Û */ => 'U', "\xC3\x9C" /* Ü */ => 'U', "\xC3\x9D" /* Ý */ => 'Y', + "\xC3\x9E" /* Þ */ => 'TH', "\xC3\x9F" /* ß */ => 'ss', "\xC3\xA0" /* à */ => 'a', + "\xC3\xA1" /* á */ => 'a', "\xC3\xA2" /* â */ => 'a', "\xC3\xA3" /* ã */ => 'a', + "\xC3\xA4" /* ä */ => 'a', "\xC3\xA5" /* å */ => 'a', "\xC3\xA6" /* æ */ => 'ae', + "\xC3\xA7" /* ç */ => 'c', "\xC3\xA8" /* è */ => 'e', "\xC3\xA9" /* é */ => 'e', + "\xC3\xAA" /* ê */ => 'e', "\xC3\xAB" /* ë */ => 'e', "\xC3\xAC" /* ì */ => 'i', + "\xC3\xAD" /* í */ => 'i', "\xC3\xAE" /* î */ => 'i', "\xC3\xAF" /* ï */ => 'i', + "\xC3\xB0" /* ð */ => 'd', "\xC3\xB1" /* ñ */ => 'n', "\xC3\xB2" /* ò */ => 'o', + "\xC3\xB3" /* ó */ => 'o', "\xC3\xB4" /* ô */ => 'o', "\xC3\xB5" /* õ */ => 'o', + "\xC3\xB6" /* ö */ => 'o', "\xC3\xB8" /* ø */ => 'o', "\xC3\xB9" /* ù */ => 'u', + "\xC3\xBA" /* ú */ => 'u', "\xC3\xBB" /* û */ => 'u', "\xC3\xBC" /* ü */ => 'u', + "\xC3\xBD" /* ý */ => 'y', "\xC3\xBE" /* þ */ => 'th', "\xC3\xBF" /* ÿ */ => 'y', + "\xC3\x98" /* Ø */ => 'O', + // Decompositions for Latin Extended-A + "\xC4\x80" /* Ā */ => 'A', "\xC4\x81" /* ā */ => 'a', "\xC4\x82" /* Ă */ => 'A', + "\xC4\x83" /* ă */ => 'a', "\xC4\x84" /* Ą */ => 'A', "\xC4\x85" /* ą */ => 'a', + "\xC4\x86" /* Ć */ => 'C', "\xC4\x87" /* ć */ => 'c', "\xC4\x88" /* Ĉ */ => 'C', + "\xC4\x89" /* ĉ */ => 'c', "\xC4\x8A" /* Ċ */ => 'C', "\xC4\x8B" /* ċ */ => 'c', + "\xC4\x8C" /* Č */ => 'C', "\xC4\x8D" /* č */ => 'c', "\xC4\x8E" /* Ď */ => 'D', + "\xC4\x8F" /* ď */ => 'd', "\xC4\x90" /* Đ */ => 'D', "\xC4\x91" /* đ */ => 'd', + "\xC4\x92" /* Ē */ => 'E', "\xC4\x93" /* ē */ => 'e', "\xC4\x94" /* Ĕ */ => 'E', + "\xC4\x95" /* ĕ */ => 'e', "\xC4\x96" /* Ė */ => 'E', "\xC4\x97" /* ė */ => 'e', + "\xC4\x98" /* Ę */ => 'E', "\xC4\x99" /* ę */ => 'e', "\xC4\x9A" /* Ě */ => 'E', + "\xC4\x9B" /* ě */ => 'e', "\xC4\x9C" /* Ĝ */ => 'G', "\xC4\x9D" /* ĝ */ => 'g', + "\xC4\x9E" /* Ğ */ => 'G', "\xC4\x9F" /* ğ */ => 'g', "\xC4\xA0" /* Ġ */ => 'G', + "\xC4\xA1" /* ġ */ => 'g', "\xC4\xA2" /* Ģ */ => 'G', "\xC4\xA3" /* ģ */ => 'g', + "\xC4\xA4" /* Ĥ */ => 'H', "\xC4\xA5" /* ĥ */ => 'h', "\xC4\xA6" /* Ħ */ => 'H', + "\xC4\xA7" /* ħ */ => 'h', "\xC4\xA8" /* Ĩ */ => 'I', "\xC4\xA9" /* ĩ */ => 'i', + "\xC4\xAA" /* Ī */ => 'I', "\xC4\xAB" /* ī */ => 'i', "\xC4\xAC" /* Ĭ */ => 'I', + "\xC4\xAD" /* ĭ */ => 'i', "\xC4\xAE" /* Į */ => 'I', "\xC4\xAF" /* į */ => 'i', + "\xC4\xB0" /* İ */ => 'I', "\xC4\xB1" /* ı */ => 'i', "\xC4\xB2" /* IJ */ => 'IJ', + "\xC4\xB3" /* ij */ => 'ij', "\xC4\xB4" /* Ĵ */ => 'J', "\xC4\xB5" /* ĵ */ => 'j', + "\xC4\xB6" /* Ķ */ => 'K', "\xC4\xB7" /* ķ */ => 'k', "\xC4\xB8" /* ĸ */ => 'k', + "\xC4\xB9" /* Ĺ */ => 'L', "\xC4\xBA" /* ĺ */ => 'l', "\xC4\xBB" /* Ļ */ => 'L', + "\xC4\xBC" /* ļ */ => 'l', "\xC4\xBD" /* Ľ */ => 'L', "\xC4\xBE" /* ľ */ => 'l', + "\xC4\xBF" /* Ŀ */ => 'L', "\xC5\x80" /* ŀ */ => 'l', "\xC5\x81" /* Ł */ => 'L', + "\xC5\x82" /* ł */ => 'l', "\xC5\x83" /* Ń */ => 'N', "\xC5\x84" /* ń */ => 'n', + "\xC5\x85" /* Ņ */ => 'N', "\xC5\x86" /* ņ */ => 'n', "\xC5\x87" /* Ň */ => 'N', + "\xC5\x88" /* ň */ => 'n', "\xC5\x89" /* ʼn */ => 'N', "\xC5\x8A" /* Ŋ */ => 'n', + "\xC5\x8B" /* ŋ */ => 'N', "\xC5\x8C" /* Ō */ => 'O', "\xC5\x8D" /* ō */ => 'o', + "\xC5\x8E" /* Ŏ */ => 'O', "\xC5\x8F" /* ŏ */ => 'o', "\xC5\x90" /* Ő */ => 'O', + "\xC5\x91" /* ő */ => 'o', "\xC5\x92" /* Œ */ => 'OE', "\xC5\x93" /* œ */ => 'oe', + "\xC5\x94" /* Ŕ */ => 'R', "\xC5\x95" /* ŕ */ => 'r', "\xC5\x96" /* Ŗ */ => 'R', + "\xC5\x97" /* ŗ */ => 'r', "\xC5\x98" /* Ř */ => 'R', "\xC5\x99" /* ř */ => 'r', + "\xC5\x9A" /* Ś */ => 'S', "\xC5\x9B" /* ś */ => 's', "\xC5\x9C" /* Ŝ */ => 'S', + "\xC5\x9D" /* ŝ */ => 's', "\xC5\x9E" /* Ş */ => 'S', "\xC5\x9F" /* ş */ => 's', + "\xC5\xA0" /* Š */ => 'S', "\xC5\xA1" /* š */ => 's', "\xC5\xA2" /* Ţ */ => 'T', + "\xC5\xA3" /* ţ */ => 't', "\xC5\xA4" /* Ť */ => 'T', "\xC5\xA5" /* ť */ => 't', + "\xC5\xA6" /* Ŧ */ => 'T', "\xC5\xA7" /* ŧ */ => 't', "\xC5\xA8" /* Ũ */ => 'U', + "\xC5\xA9" /* ũ */ => 'u', "\xC5\xAA" /* Ū */ => 'U', "\xC5\xAB" /* ū */ => 'u', + "\xC5\xAC" /* Ŭ */ => 'U', "\xC5\xAD" /* ŭ */ => 'u', "\xC5\xAE" /* Ů */ => 'U', + "\xC5\xAF" /* ů */ => 'u', "\xC5\xB0" /* Ű */ => 'U', "\xC5\xB1" /* ű */ => 'u', + "\xC5\xB2" /* Ų */ => 'U', "\xC5\xB3" /* ų */ => 'u', "\xC5\xB4" /* Ŵ */ => 'W', + "\xC5\xB5" /* ŵ */ => 'w', "\xC5\xB6" /* Ŷ */ => 'Y', "\xC5\xB7" /* ŷ */ => 'y', + "\xC5\xB8" /* Ÿ */ => 'Y', "\xC5\xB9" /* Ź */ => 'Z', "\xC5\xBA" /* ź */ => 'z', + "\xC5\xBB" /* Ż */ => 'Z', "\xC5\xBC" /* ż */ => 'z', "\xC5\xBD" /* Ž */ => 'Z', + "\xC5\xBE" /* ž */ => 'z', "\xC5\xBF" /* ſ */ => 's', + // Decompositions for Latin Extended-B + "\xC8\x98" /* Ș */ => 'S', "\xC8\x99" /* ș */ => 's', + "\xC8\x9A" /* Ț */ => 'T', "\xC8\x9B" /* ț */ => 't', + // unmarked + "\xC6\xA0" /* Ơ */ => 'O', "\xC6\xA1" /* ơ */ => 'o', + "\xC6\xAF" /* Ư */ => 'U', "\xC6\xB0" /* ư */ => 'u', + // grave accent + "\xE1\xBA\xA6" /* Ầ */ => 'A', "\xE1\xBA\xA7" /* ầ */ => 'a', + "\xE1\xBA\xB0" /* Ằ */ => 'A', "\xE1\xBA\xB1" /* ằ */ => 'a', + "\xE1\xBB\x80" /* Ề */ => 'E', "\xE1\xBB\x81" /* ề */ => 'e', + "\xE1\xBB\x92" /* Ồ */ => 'O', "\xE1\xBB\x93" /* ồ */ => 'o', + "\xE1\xBB\x9C" /* Ờ */ => 'O', "\xE1\xBB\x9D" /* ờ */ => 'o', + "\xE1\xBB\xAA" /* Ừ */ => 'U', "\xE1\xBB\xAB" /* ừ */ => 'u', + "\xE1\xBB\xB2" /* Ỳ */ => 'Y', "\xE1\xBB\xB3" /* ỳ */ => 'y', + // hook + "\xE1\xBA\xA2" /* Ả */ => 'A', "\xE1\xBA\xA3" /* ả */ => 'a', + "\xE1\xBA\xA8" /* Ẩ */ => 'A', "\xE1\xBA\xA9" /* ẩ */ => 'a', + "\xE1\xBA\xB2" /* Ẳ */ => 'A', "\xE1\xBA\xB3" /* ẳ */ => 'a', + "\xE1\xBA\xBA" /* Ẻ */ => 'E', "\xE1\xBA\xBB" /* ẻ */ => 'e', + "\xE1\xBB\x82" /* Ể */ => 'E', "\xE1\xBB\x83" /* ể */ => 'e', + "\xE1\xBB\x88" /* Ỉ */ => 'I', "\xE1\xBB\x89" /* ỉ */ => 'i', + "\xE1\xBB\x8E" /* Ỏ */ => 'O', "\xE1\xBB\x8F" /* ỏ */ => 'o', + "\xE1\xBB\x94" /* Ổ */ => 'O', "\xE1\xBB\x95" /* ổ */ => 'o', + "\xE1\xBB\x9E" /* Ở */ => 'O', "\xE1\xBB\x9F" /* ở */ => 'o', + "\xE1\xBB\xA6" /* Ủ */ => 'U', "\xE1\xBB\xA7" /* ủ */ => 'u', + "\xE1\xBB\xAC" /* Ử */ => 'U', "\xE1\xBB\xAD" /* ử */ => 'u', + "\xE1\xBB\xB6" /* Ỷ */ => 'Y', "\xE1\xBB\xB7" /* ỷ */ => 'y', + // tilde + "\xE1\xBA\xAA" /* Ẫ */ => 'A', "\xE1\xBA\xAB" /* ẫ */ => 'a', + "\xE1\xBA\xB4" /* Ẵ */ => 'A', "\xE1\xBA\xB5" /* ẵ */ => 'a', + "\xE1\xBA\xBC" /* Ẽ */ => 'E', "\xE1\xBA\xBD" /* ẽ */ => 'e', + "\xE1\xBB\x84" /* Ễ */ => 'E', "\xE1\xBB\x85" /* ễ */ => 'e', + "\xE1\xBB\x96" /* Ỗ */ => 'O', "\xE1\xBB\x97" /* ỗ */ => 'o', + "\xE1\xBB\xA0" /* Ỡ */ => 'O', "\xE1\xBB\xA1" /* ỡ */ => 'o', + "\xE1\xBB\xAE" /* Ữ */ => 'U', "\xE1\xBB\xAF" /* ữ */ => 'u', + "\xE1\xBB\xB8" /* Ỹ */ => 'Y', "\xE1\xBB\xB9" /* ỹ */ => 'y', + // acute accent + "\xE1\xBA\xA4" /* Ấ */ => 'A', "\xE1\xBA\xA5" /* ấ */ => 'a', + "\xE1\xBA\xAE" /* Ắ */ => 'A', "\xE1\xBA\xAF" /* ắ */ => 'a', + "\xE1\xBA\xBE" /* Ế */ => 'E', "\xE1\xBA\xBF" /* ế */ => 'e', + "\xE1\xBB\x90" /* Ố */ => 'O', "\xE1\xBB\x91" /* ố */ => 'o', + "\xE1\xBB\x9A" /* Ớ */ => 'O', "\xE1\xBB\x9B" /* ớ */ => 'o', + "\xE1\xBB\xA8" /* Ứ */ => 'U', "\xE1\xBB\xA9" /* ứ */ => 'u', + // dot below + "\xE1\xBA\xA0" /* Ạ */ => 'A', "\xE1\xBA\xA1" /* ạ */ => 'a', + "\xE1\xBA\xAC" /* Ậ */ => 'A', "\xE1\xBA\xAD" /* ậ */ => 'a', + "\xE1\xBA\xB6" /* Ặ */ => 'A', "\xE1\xBA\xB7" /* ặ */ => 'a', + "\xE1\xBA\xB8" /* Ẹ */ => 'E', "\xE1\xBA\xB9" /* ẹ */ => 'e', + "\xE1\xBB\x86" /* Ệ */ => 'E', "\xE1\xBB\x87" /* ệ */ => 'e', + "\xE1\xBB\x8A" /* Ị */ => 'I', "\xE1\xBB\x8B" /* ị */ => 'i', + "\xE1\xBB\x8C" /* Ọ */ => 'O', "\xE1\xBB\x8D" /* ọ */ => 'o', + "\xE1\xBB\x98" /* Ộ */ => 'O', "\xE1\xBB\x99" /* ộ */ => 'o', + "\xE1\xBB\xA2" /* Ợ */ => 'O', "\xE1\xBB\xA3" /* ợ */ => 'o', + "\xE1\xBB\xA4" /* Ụ */ => 'U', "\xE1\xBB\xA5" /* ụ */ => 'u', + "\xE1\xBB\xB0" /* Ự */ => 'U', "\xE1\xBB\xB1" /* ự */ => 'u', + "\xE1\xBB\xB4" /* Ỵ */ => 'Y', "\xE1\xBB\xB5" /* ỵ */ => 'y', + ); + } + + /** + * Tests that "normalizer_normalize" exists and works + * @return bool + */ + static public function hasNormalizerSupport() { + static $ret = null; + if (null === $ret) { + $form_c = "\xC3\x85"; // 'LATIN CAPITAL LETTER A WITH RING ABOVE' (U+00C5) + $form_d = "A\xCC\x8A"; // A followed by 'COMBINING RING ABOVE' (U+030A) + $ret = (function_exists('normalizer_normalize') + && $form_c === normalizer_normalize($form_d)); + } + return $ret; + } +} diff --git a/engine/classes/ElggVolatileMetadataCache.php b/engine/classes/ElggVolatileMetadataCache.php new file mode 100644 index 000000000..8a33c198d --- /dev/null +++ b/engine/classes/ElggVolatileMetadataCache.php @@ -0,0 +1,347 @@ +<?php +/** + * ElggVolatileMetadataCache + * In memory cache of known metadata values stored by entity. + * + * @package Elgg.Core + * @subpackage Cache + * + * @access private + */ +class ElggVolatileMetadataCache { + + /** + * The cached values (or null for known to be empty). If the portion of the cache + * is synchronized, missing values are assumed to indicate that values do not + * exist in storage, otherwise, we don't know what's there. + * + * @var array + */ + protected $values = array(); + + /** + * Does the cache know that it contains all names fetch-able from storage? + * The keys are entity GUIDs and either the value exists (true) or it's not set. + * + * @var array + */ + protected $isSynchronized = array(); + + /** + * @var null|bool + */ + protected $ignoreAccess = null; + + /** + * @param int $entity_guid + * + * @param array $values + */ + public function saveAll($entity_guid, array $values) { + if (!$this->getIgnoreAccess()) { + $this->values[$entity_guid] = $values; + $this->isSynchronized[$entity_guid] = true; + } + } + + /** + * @param int $entity_guid + * + * @return array + */ + public function loadAll($entity_guid) { + if (isset($this->values[$entity_guid])) { + return $this->values[$entity_guid]; + } else { + return array(); + } + } + + /** + * Declare that there may be fetch-able metadata names in storage that this + * cache doesn't know about + * + * @param int $entity_guid + */ + public function markOutOfSync($entity_guid) { + unset($this->isSynchronized[$entity_guid]); + } + + /** + * @param $entity_guid + * + * @return bool + */ + public function isSynchronized($entity_guid) { + return isset($this->isSynchronized[$entity_guid]); + } + + /** + * @param int $entity_guid + * + * @param string $name + * + * @param array|int|string|null $value null means it is known that there is no + * fetch-able metadata under this name + * @param bool $allow_multiple + */ + public function save($entity_guid, $name, $value, $allow_multiple = false) { + if ($this->getIgnoreAccess()) { + // we don't know if what gets saves here will be available to user once + // access control returns, hence it's best to forget :/ + $this->markUnknown($entity_guid, $name); + } else { + if ($allow_multiple) { + if ($this->isKnown($entity_guid, $name)) { + $existing = $this->load($entity_guid, $name); + if ($existing !== null) { + $existing = (array) $existing; + $existing[] = $value; + $value = $existing; + } + } else { + // we don't know whether there are unknown values, so it's + // safest to leave that assumption + $this->markUnknown($entity_guid, $name); + return; + } + } + $this->values[$entity_guid][$name] = $value; + } + } + + /** + * Warning: You should always call isKnown() beforehand to verify that this + * function's return value should be trusted (otherwise a null return value + * is ambiguous). + * + * @param int $entity_guid + * + * @param string $name + * + * @return array|string|int|null null = value does not exist + */ + public function load($entity_guid, $name) { + if (isset($this->values[$entity_guid]) && array_key_exists($name, $this->values[$entity_guid])) { + return $this->values[$entity_guid][$name]; + } else { + return null; + } + } + + /** + * Forget about this metadata entry. We don't want to try to guess what the + * next fetch from storage will return + * + * @param int $entity_guid + * + * @param string $name + */ + public function markUnknown($entity_guid, $name) { + unset($this->values[$entity_guid][$name]); + $this->markOutOfSync($entity_guid); + } + + /** + * If true, load() will return an accurate value for this name + * + * @param int $entity_guid + * + * @param string $name + * + * @return bool + */ + public function isKnown($entity_guid, $name) { + if (isset($this->isSynchronized[$entity_guid])) { + return true; + } else { + return (isset($this->values[$entity_guid]) && array_key_exists($name, $this->values[$entity_guid])); + } + + } + + /** + * Declare that metadata under this name is known to be not fetch-able from storage + * + * @param int $entity_guid + * + * @param string $name + * + * @return array + */ + public function markEmpty($entity_guid, $name) { + $this->values[$entity_guid][$name] = null; + } + + /** + * Forget about all metadata for an entity + * + * @param int $entity_guid + */ + public function clear($entity_guid) { + $this->values[$entity_guid] = array(); + $this->markOutOfSync($entity_guid); + } + + /** + * Clear entire cache and mark all entities as out of sync + */ + public function flush() { + $this->values = array(); + $this->isSynchronized = array(); + } + + /** + * Use this value instead of calling elgg_get_ignore_access(). By default that + * function will be called. + * + * This setting makes this component a little more loosely-coupled. + * + * @param bool $ignore + */ + public function setIgnoreAccess($ignore) { + $this->ignoreAccess = (bool) $ignore; + } + + /** + * Tell the cache to call elgg_get_ignore_access() to determing access status. + */ + public function unsetIgnoreAccess() { + $this->ignoreAccess = null; + } + + /** + * @return bool + */ + protected function getIgnoreAccess() { + if (null === $this->ignoreAccess) { + return elgg_get_ignore_access(); + } else { + return $this->ignoreAccess; + } + } + + /** + * Invalidate based on options passed to the global *_metadata functions + * + * @param string $action Action performed on metadata. "delete", "disable", or "enable" + * + * @param array $options Options passed to elgg_(delete|disable|enable)_metadata + * + * "guid" if given, invalidation will be limited to this entity + * + * "metadata_name" if given, invalidation will be limited to metadata with this name + */ + public function invalidateByOptions($action, array $options) { + // remove as little as possible, optimizing for common cases + if (empty($options['guid'])) { + // safest to clear everything unless we want to make this even more complex :( + $this->flush(); + } else { + if (empty($options['metadata_name'])) { + // safest to clear the whole entity + $this->clear($options['guid']); + } else { + switch ($action) { + case 'delete': + $this->markEmpty($options['guid'], $options['metadata_name']); + break; + default: + $this->markUnknown($options['guid'], $options['metadata_name']); + } + } + } + } + + /** + * @param int|array $guids + */ + public function populateFromEntities($guids) { + if (empty($guids)) { + return; + } + if (!is_array($guids)) { + $guids = array($guids); + } + $guids = array_unique($guids); + + // could be useful at some point in future + //$guids = $this->filterMetadataHeavyEntities($guids); + + $db_prefix = elgg_get_config('dbprefix'); + $options = array( + 'guids' => $guids, + 'limit' => 0, + 'callback' => false, + 'joins' => array( + "JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id", + "JOIN {$db_prefix}metastrings n ON n_table.name_id = n.id", + ), + '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); + + // build up metadata for each entity, save when GUID changes (or data ends) + $last_guid = null; + $metadata = array(); + $last_row_idx = count($data) - 1; + foreach ($data as $i => $row) { + $name = $row->name; + $value = ($row->value_type === 'text') ? $row->value : (int) $row->value; + $guid = $row->entity_guid; + if ($guid !== $last_guid) { + if ($last_guid) { + $this->saveAll($last_guid, $metadata); + } + $metadata = array(); + } + if (isset($metadata[$name])) { + $metadata[$name] = (array) $metadata[$name]; + $metadata[$name][] = $value; + } else { + $metadata[$name] = $value; + } + if (($i == $last_row_idx)) { + $this->saveAll($guid, $metadata); + } + $last_guid = $guid; + } + } + + /** + * Filter out entities whose concatenated metadata values (INTs casted as string) + * exceed a threshold in characters. This could be used to avoid overpopulating the + * cache if RAM usage becomes an issue. + * + * @param array $guids GUIDs of entities to examine + * + * @param int $limit Limit in characters of all metadata (with ints casted to strings) + * + * @return array + */ + public function filterMetadataHeavyEntities(array $guids, $limit = 1024000) { + $db_prefix = elgg_get_config('dbprefix'); + + $options = array( + 'guids' => $guids, + 'limit' => 0, + 'callback' => false, + 'joins' => "JOIN {$db_prefix}metastrings v ON n_table.value_id = v.id", + 'selects' => array('SUM(LENGTH(v.string)) AS bytes'), + 'order_by' => 'n_table.entity_guid, n_table.time_created ASC', + 'group_by' => 'n_table.entity_guid', + ); + $data = elgg_get_metadata($options); + // don't cache if metadata for entity is over 10MB (or rolled INT) + foreach ($data as $row) { + if ($row->bytes > $limit || $row->bytes < 0) { + array_splice($guids, array_search($row->entity_guid, $guids), 1); + } + } + return $guids; + } +} 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/actions.php b/engine/lib/actions.php index 3a7c02488..53b185dea 100644 --- a/engine/lib/actions.php +++ b/engine/lib/actions.php @@ -82,44 +82,28 @@ function action($action, $forwarder = "") { $forwarder = str_replace(elgg_get_site_url(), "", $forwarder); $forwarder = str_replace("http://", "", $forwarder); $forwarder = str_replace("@", "", $forwarder); - if (substr($forwarder, 0, 1) == "/") { $forwarder = substr($forwarder, 1); } - if (isset($CONFIG->actions[$action])) { - if (elgg_is_admin_logged_in() || ($CONFIG->actions[$action]['access'] !== 'admin')) { - if (elgg_is_logged_in() || ($CONFIG->actions[$action]['access'] === 'public')) { - - // Trigger action event - // @todo This is only called before the primary action is called. - $event_result = true; - $event_result = elgg_trigger_plugin_hook('action', $action, null, $event_result); - - // Include action - // Event_result being false doesn't produce an error - // since i assume this will be handled in the hook itself. - // @todo make this better! - if ($event_result) { - if (!include($CONFIG->actions[$action]['file'])) { - register_error(elgg_echo('actionnotfound', array($action))); - } - } - } else { - register_error(elgg_echo('actionloggedout')); + if (!isset($CONFIG->actions[$action])) { + register_error(elgg_echo('actionundefined', array($action))); + } elseif (!elgg_is_admin_logged_in() && ($CONFIG->actions[$action]['access'] === 'admin')) { + register_error(elgg_echo('actionunauthorized')); + } elseif (!elgg_is_logged_in() && ($CONFIG->actions[$action]['access'] !== 'public')) { + register_error(elgg_echo('actionloggedout')); + } else { + // Returning falsy doesn't produce an error + // We assume this will be handled in the hook itself. + if (elgg_trigger_plugin_hook('action', $action, null, true)) { + if (!include($CONFIG->actions[$action]['file'])) { + register_error(elgg_echo('actionnotfound', array($action))); } - } else { - register_error(elgg_echo('actionunauthorized')); } - } else { - register_error(elgg_echo('actionundefined', array($action))); } - if (!empty($forwarder)) { - forward($forwarder); - } else { - forward(REFERER); - } + $forwarder = empty($forwarder) ? REFERER : $forwarder; + forward($forwarder); } /** 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 3026a78e3..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; + } } } } @@ -1070,7 +1078,11 @@ function _elgg_php_error_handler($errno, $errmsg, $filename, $linenum, $vars) { case E_WARNING : case E_USER_WARNING : case E_RECOVERABLE_ERROR: // (e.g. type hint violation) - error_log("PHP WARNING: $error"); + + // check if the error wasn't suppressed by the error control operator (@) + if (error_reporting()) { + error_log("PHP WARNING: $error"); + } break; default: @@ -1575,7 +1587,7 @@ function elgg_http_url_is_identical($url1, $url2, $ignore_params = array('offset * @param bool $strict Return array key if it's set, even if empty. If false, * return $default if the array key is unset or empty. * - * @return void + * @return mixed * @since 1.8.0 */ function elgg_extract($key, array $array, $default = null, $strict = true) { @@ -1879,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 abfe07276..fda554388 100644 --- a/engine/lib/entities.php +++ b/engine/lib/entities.php @@ -17,20 +17,20 @@ 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. * * @param int $guid The entity guid * - * @return void + * @return null * @access private */ function invalidate_cache_for_entity($guid) { @@ -39,6 +39,8 @@ function invalidate_cache_for_entity($guid) { $guid = (int)$guid; unset($ENTITY_CACHE[$guid]); + + elgg_get_metadata_cache()->clear($guid); } /** @@ -48,14 +50,35 @@ function invalidate_cache_for_entity($guid) { * * @param ElggEntity $entity Entity to cache * - * @return void + * @return null * @see retrieve_cached_entity() * @see invalidate_cache_for_entity() * @access private + * TODO(evan): Use an ElggCache object */ function cache_entity(ElggEntity $entity) { global $ENTITY_CACHE; + // 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 (!($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) { + $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; } @@ -64,7 +87,7 @@ function cache_entity(ElggEntity $entity) { * * @param int $guid The guid * - * @return void + * @return ElggEntity|bool false if entity not cached, or not fully loaded * @see cache_entity() * @see invalidate_cache_for_entity() * @access private @@ -72,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]; @@ -133,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; } /** @@ -163,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; +} - $SUBTYPE_CACHE[$subtype_id] = $result; - return $result->subtype; +/** + * 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; + + 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; + } } /** @@ -210,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; } /** @@ -242,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; } /** @@ -290,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; @@ -313,6 +357,10 @@ function add_subtype($type, $subtype, $class = "") { /** * Removes a registered ElggEntity type, subtype, and classname. * + * @warning You do not want to use this function. If you want to unregister + * a class for a subtype, use update_subtype(). Using this function will + * permanently orphan all the objects created with the specified subtype. + * * @param string $type Type * @param string $subtype Subtype * @@ -342,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; } /** @@ -589,12 +646,14 @@ function get_entity_as_row($guid) { * * @param stdClass $row The row of the entry in the entities table. * - * @return object|false + * @return ElggEntity|false * @link http://docs.elgg.org/DataModel/Entities * @see get_entity_as_row() * @see add_subtype() * @see get_entity() * @access private + * + * @throws ClassException|InstallationException */ function entity_row_to_elggstar($row) { if (!($row instanceof stdClass)) { @@ -672,29 +731,53 @@ function entity_row_to_elggstar($row) { * @link http://docs.elgg.org/DataModel/Entities */ function get_entity($guid) { - static $newentity_cache; - $new_entity = false; + // This should not be a static local var. Notice that cache writing occurs in a completely + // different instance outside this function. + // @todo We need a single Memcache instance with a shared pool of namespace wrappers. This function would pull an instance from the pool. + static $shared_cache; // We could also use: if (!(int) $guid) { return FALSE }, // but that evaluates to a false positive for $guid = TRUE. // This is a bit slower, but more thorough. if (!is_numeric($guid) || $guid === 0 || $guid === '0') { - return FALSE; + return false; + } + + // Check local cache first + $new_entity = retrieve_cached_entity($guid); + if ($new_entity) { + return $new_entity; } - if ((!$newentity_cache) && (is_memcache_available())) { - $newentity_cache = new ElggMemcache('new_entity_cache'); + // Check shared memory cache, if available + if (null === $shared_cache) { + if (is_memcache_available()) { + $shared_cache = new ElggMemcache('new_entity_cache'); + } else { + $shared_cache = false; + } } - if ($newentity_cache) { - $new_entity = $newentity_cache->load($guid); + // until ACLs in memcache, DB query is required to determine access + $entity_row = get_entity_as_row($guid); + if (!$entity_row) { + return false; } - if ($new_entity) { - return $new_entity; + if ($shared_cache) { + $cached_entity = $shared_cache->load($guid); + // @todo store ACLs in memcache http://trac.elgg.org/ticket/3018#comment:3 + if ($cached_entity) { + // @todo use ACL and cached entity access_id to determine if user can see it + return $cached_entity; + } } - return entity_row_to_elggstar(get_entity_as_row($guid)); + $new_entity = entity_row_to_elggstar($entity_row); + if ($new_entity) { + cache_entity($new_entity); + } + return $new_entity; } /** @@ -936,6 +1019,26 @@ function elgg_get_entities(array $options = array()) { } $dt = get_data($query, $options['callback']); + if ($dt) { + // populate entity and metadata caches + $guids = array(); + foreach ($dt as $item) { + // A custom callback could result in items that aren't ElggEntity's, so check for them + if ($item instanceof ElggEntity) { + cache_entity($item); + // plugins usually have only settings + if (!$item instanceof ElggPlugin) { + $guids[] = $item->guid; + } + } + } + // @todo Without this, recursive delete fails. See #4568 + reset($dt); + + if ($guids) { + elgg_get_metadata_cache()->populateFromEntities($guids); + } + } return $dt; } else { $total = get_data_row($query); @@ -1109,7 +1212,7 @@ function elgg_get_entity_type_subtype_where_sql($table, $types, $subtypes, $pair * best to provide in table.column format. * @param NULL|array $guids Array of GUIDs. * - * @return false|str + * @return false|string * @since 1.8.0 * @access private */ @@ -1158,7 +1261,7 @@ function elgg_get_guid_based_where_sql($column, $guids) { * @param NULL|int $time_updated_upper Time updated upper limit * @param NULL|int $time_updated_lower Time updated lower limit * - * @return FALSE|str FALSE on fail, string on success. + * @return FALSE|string FALSE on fail, string on success. * @since 1.7.0 * @access private */ @@ -1260,7 +1363,7 @@ function elgg_list_entities(array $options = array(), $getter = 'elgg_get_entiti * @param string $subtype The subtype of entity * @param int $container_guid The container GUID that the entinties belong to * @param int $site_guid The site GUID - * @param str $order_by Order_by SQL order by clause + * @param string $order_by Order_by SQL order by clause * * @return array|false Either an array months as YYYYMM, or false on failure */ @@ -1408,6 +1511,7 @@ function disable_entity($guid, $reason = "", $recursive = true) { $entity->disableMetadata(); $entity->disableAnnotations(); + invalidate_cache_for_entity($guid); $res = update_data("UPDATE {$CONFIG->dbprefix}entities SET enabled = 'no' @@ -1604,7 +1708,7 @@ function delete_entity($guid, $recursive = true) { * @param string $returnvalue Return value from previous hook * @param array $params The parameters, passed 'guid' and 'varname' * - * @return void + * @return ElggMetadata|null * @elgg_plugin_hook_handler volatile metadata * @todo investigate more. * @access private @@ -1649,6 +1753,8 @@ function volatile_data_export_plugin_hook($hook, $entity_type, $returnvalue, $pa * @elgg_event_handler export all * @return mixed * @access private + * + * @throws InvalidParameterException|InvalidClassException */ function export_entity_plugin_hook($hook, $entity_type, $returnvalue, $params) { // Sanity check values @@ -1691,6 +1797,8 @@ function export_entity_plugin_hook($hook, $entity_type, $returnvalue, $params) { * @return ElggEntity the unsaved entity which should be populated by items. * @todo Remove this. * @access private + * + * @throws ClassException|InstallationException|ImportException */ function oddentity_to_elggentity(ODDEntity $element) { $class = $element->getAttribute('class'); @@ -1702,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(); @@ -1762,11 +1870,13 @@ function oddentity_to_elggentity(ODDEntity $element) { * @elgg_plugin_hook_handler import all * @todo document * @access private + * + * @throws ImportException */ 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); @@ -1808,8 +1918,6 @@ function import_entity_plugin_hook($hook, $entity_type, $returnvalue, $params) { * @link http://docs.elgg.org/Entities/AccessControl */ function can_edit_entity($entity_guid, $user_guid = 0) { - global $CONFIG; - $user_guid = (int)$user_guid; $user = get_entity($user_guid); if (!$user) { @@ -1933,7 +2041,7 @@ function get_entity_url($entity_guid) { * @param string $entity_subtype The entity subtype * @param string $function_name The function to register * - * @return true|false Depending on success + * @return bool Depending on success * @see get_entity_url() * @see ElggEntity::getURL() * @since 1.8.0 @@ -1941,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; } @@ -1969,7 +2077,7 @@ function elgg_register_entity_url_handler($entity_type, $entity_subtype, $functi * @param string $type The type of entity (object, site, user, group) * @param string $subtype The subtype to register (may be blank) * - * @return true|false Depending on success + * @return bool Depending on success * @see get_registered_entity_types() * @link http://docs.elgg.org/Search * @link http://docs.elgg.org/Tutorials/Search @@ -2006,7 +2114,7 @@ function elgg_register_entity_type($type, $subtype = null) { * @param string $type The type of entity (object, site, user, group) * @param string $subtype The subtype to register (may be blank) * - * @return true|false Depending on success + * @return bool Depending on success * @see elgg_register_entity_type() */ function unregister_entity_type($type, $subtype) { @@ -2073,7 +2181,7 @@ function get_registered_entity_types($type = null) { * @param string $type The type of entity (object, site, user, group) * @param string $subtype The subtype (may be blank) * - * @return true|false Depending on whether or not the type has been registered + * @return bool Depending on whether or not the type has been registered */ function is_registered_entity_type($type, $subtype = null) { global $CONFIG; @@ -2273,7 +2381,7 @@ function entities_gc() { /** * Runs unit tests for the entity objects. * - * @param sting $hook unit_test + * @param string $hook unit_test * @param string $type system * @param mixed $value Array of tests * @param mixed $params Params 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/languages.php b/engine/lib/languages.php index 15c48f902..98006f7cd 100644 --- a/engine/lib/languages.php +++ b/engine/lib/languages.php @@ -50,8 +50,11 @@ function elgg_echo($message_key, $args = array(), $language = "") { $string = $CONFIG->translations[$language][$message_key]; } else if (isset($CONFIG->translations["en"][$message_key])) { $string = $CONFIG->translations["en"][$message_key]; + $lang = $CONFIG->translations["en"][$language]; + elgg_log(sprintf('Missing %s translation for "%s" language key', $lang, $message_key), 'NOTICE'); } else { $string = $message_key; + elgg_log(sprintf('Missing English translation for "%s" language key', $message_key), 'NOTICE'); } // only pass through if we have arguments to allow backward compatibility diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index 0ff3a43dc..f76c20f24 100644 --- a/engine/lib/metadata.php +++ b/engine/lib/metadata.php @@ -12,7 +12,7 @@ * * @param stdClass $row An object from the database * - * @return stdClass or ElggMetadata + * @return stdClass|ElggMetadata * @access private */ function row_to_elggmetadata($row) { @@ -30,7 +30,7 @@ function row_to_elggmetadata($row) { * * @param int $id The id of the metadata object being retrieved. * - * @return false|ElggMetadata + * @return ElggMetadata|false FALSE if not found */ function elgg_get_metadata_from_id($id) { return elgg_get_metastring_based_object_from_id($id, 'metadata'); @@ -64,7 +64,7 @@ function elgg_delete_metadata_by_id($id) { * @param int $access_id Default is ACCESS_PRIVATE * @param bool $allow_multiple Allow multiple values for one key. Default is FALSE * - * @return int/bool id of metadata or FALSE if failure + * @return int|false id of metadata or FALSE if failure */ function create_metadata($entity_guid, $name, $value, $value_type = '', $owner_guid = 0, $access_id = ACCESS_PRIVATE, $allow_multiple = false) { @@ -90,8 +90,6 @@ function create_metadata($entity_guid, $name, $value, $value_type = '', $owner_g $access_id = (int)$access_id; - $id = false; - $query = "SELECT * from {$CONFIG->dbprefix}metadata" . " WHERE entity_guid = $entity_guid and name_id=" . add_metastring($name) . " limit 1"; @@ -106,34 +104,33 @@ function create_metadata($entity_guid, $name, $value, $value_type = '', $owner_g } else { // Support boolean types if (is_bool($value)) { - if ($value) { - $value = 1; - } else { - $value = 0; - } + $value = (int) $value; } // Add the metastrings - $value = add_metastring($value); - if (!$value) { + $value_id = add_metastring($value); + if (!$value_id) { return false; } - $name = add_metastring($name); - if (!$name) { + $name_id = add_metastring($name); + if (!$name_id) { return false; } // If ok then add it $query = "INSERT into {$CONFIG->dbprefix}metadata" . " (entity_guid, name_id, value_id, value_type, owner_guid, time_created, access_id)" - . " VALUES ($entity_guid, '$name','$value','$value_type', $owner_guid, $time, $access_id)"; + . " VALUES ($entity_guid, '$name_id','$value_id','$value_type', $owner_guid, $time, $access_id)"; $id = insert_data($query); if ($id !== false) { $obj = elgg_get_metadata_from_id($id); if (elgg_trigger_event('create', 'metadata', $obj)) { + + elgg_get_metadata_cache()->save($entity_guid, $name, $value, $allow_multiple); + return $id; } else { elgg_delete_metadata_by_id($id); @@ -175,6 +172,7 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i } if ($metabyname_memcache) { + // @todo fix memcache (name_id is not a property of ElggMetadata) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } @@ -187,15 +185,9 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i $access_id = (int)$access_id; - $access = get_access_sql_suffix(); - // Support boolean types (as integers) if (is_bool($value)) { - if ($value) { - $value = 1; - } else { - $value = 0; - } + $value = (int) $value; } // Add the metastring @@ -216,6 +208,9 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i $result = update_data($query); if ($result !== false) { + + elgg_get_metadata_cache()->save($md->entity_guid, $name, $value); + // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. @@ -234,7 +229,7 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i * associative arrays and there is no guarantee on the ordering in the array. * * @param int $entity_guid The entity to attach the metadata to - * @param string $name_and_values Associative array - a value can be a string, number, bool + * @param array $name_and_values Associative array - a value can be a string, number, bool * @param string $value_type 'text', 'integer', or '' for automatic detection * @param int $owner_guid GUID of entity that owns the metadata * @param int $access_id Default is ACCESS_PRIVATE @@ -308,6 +303,8 @@ function elgg_delete_metadata(array $options) { return false; } + elgg_get_metadata_cache()->invalidateByOptions('delete', $options); + $options['metastring_type'] = 'metadata'; return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback', false); } @@ -328,6 +325,8 @@ function elgg_disable_metadata(array $options) { return false; } + elgg_get_metadata_cache()->invalidateByOptions('disable', $options); + $options['metastring_type'] = 'metadata'; return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', false); } @@ -348,6 +347,8 @@ function elgg_enable_metadata(array $options) { return false; } + elgg_get_metadata_cache()->invalidateByOptions('enable', $options); + $options['metastring_type'] = 'metadata'; return elgg_batch_metastring_based_objects($options, 'elgg_batch_enable_callback'); } @@ -361,13 +362,24 @@ function elgg_enable_metadata(array $options) { * options available to elgg_get_entities(). Supports * the singular option shortcut. * - * NB: Using metadata_names and metadata_values results in a + * @note Using metadata_names and metadata_values results in a * "names IN (...) AND values IN (...)" clause. This is subtly * differently than default multiple metadata_name_value_pairs, which use * "(name = value) AND (name = value)" clauses. * * When in doubt, use name_value_pairs. * + * To ask for entities that do not have a metadata value, use a custom + * where clause like this: + * + * $options['wheres'][] = "NOT EXISTS ( + * SELECT 1 FROM {$dbprefix}metadata md + * WHERE md.entity_guid = e.guid + * AND md.name_id = $name_metastring_id + * AND md.value_id = $value_metastring_id)"; + * + * Note the metadata name and value has been denormalized in the above example. + * * @see elgg_get_entities * * @param array $options Array in format: @@ -438,16 +450,16 @@ function elgg_get_entities_from_metadata(array $options = array()) { * This function is reused for annotations because the tables are * exactly the same. * - * @param string $e_table Entities table name - * @param string $n_table Normalized metastrings table name (Where entities, + * @param string $e_table Entities table name + * @param string $n_table Normalized metastrings table name (Where entities, * values, and names are joined. annotations / metadata) - * @param arr|null $names Array of names - * @param arr|null $values Array of values - * @param arr|null $pairs Array of names / values / operands - * @param and|or $pair_operator Operator to use to join the where clauses for pairs - * @param bool $case_sensitive Case sensitive metadata names? - * @param arr|null $order_by_metadata Array of names / direction - * @param arr|null $owner_guids Array of owner GUIDs + * @param array|null $names Array of names + * @param array|null $values Array of values + * @param array|null $pairs Array of names / values / operands + * @param string $pair_operator ("AND" or "OR") Operator to use to join the where clauses for pairs + * @param bool $case_sensitive Case sensitive metadata names? + * @param array|null $order_by_metadata Array of names / direction + * @param array|null $owner_guids Array of owner GUIDs * * @return FALSE|array False on fail, array('joins', 'wheres') * @since 1.7.0 @@ -721,6 +733,8 @@ function elgg_list_entities_from_metadata($options) { * * @return array * @access private + * + * @throws InvalidParameterException */ function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params) { // Sanity check values @@ -732,15 +746,13 @@ function export_metadata_plugin_hook($hook, $entity_type, $returnvalue, $params) throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonArrayReturnValue')); } - $guid = (int)$params['guid']; - $name = $params['name']; - $result = elgg_get_metadata(array( - 'guid' => $guid, - 'limit' => 0 + 'guid' => (int)$params['guid'], + 'limit' => 0, )); if ($result) { + /* @var ElggMetadata[] $result */ foreach ($result as $r) { $returnvalue[] = $r->export(); } @@ -878,6 +890,50 @@ function elgg_register_metadata_url_handler($extender_name, $function) { return elgg_register_extender_url_handler('metadata', $extender_name, $function); } +/** + * Get the global metadata cache instance + * + * @return ElggVolatileMetadataCache + * + * @access private + */ +function elgg_get_metadata_cache() { + global $CONFIG; + if (empty($CONFIG->local_metadata_cache)) { + $CONFIG->local_metadata_cache = new ElggVolatileMetadataCache(); + } + return $CONFIG->local_metadata_cache; +} + +/** + * Invalidate the metadata cache based on options passed to various *_metadata functions + * + * @param string $action Action performed on metadata. "delete", "disable", or "enable" + * + * @param array $options Options passed to elgg_(delete|disable|enable)_metadata + */ +function elgg_invalidate_metadata_cache($action, array $options) { + // remove as little as possible, optimizing for common cases + $cache = elgg_get_metadata_cache(); + if (empty($options['guid'])) { + // safest to clear everything unless we want to make this even more complex :( + $cache->flush(); + } else { + if (empty($options['metadata_name'])) { + // safest to clear the whole entity + $cache->clear($options['guid']); + } else { + switch ($action) { + case 'delete': + $cache->markEmpty($options['guid'], $options['metadata_name']); + break; + default: + $cache->markUnknown($options['guid'], $options['metadata_name']); + } + } + } +} + /** Register the hook */ elgg_register_plugin_hook_handler("export", "all", "export_metadata_plugin_hook", 2); @@ -901,5 +957,6 @@ elgg_register_plugin_hook_handler('unit_test', 'system', 'metadata_test'); function metadata_test($hook, $type, $value, $params) { global $CONFIG; $value[] = $CONFIG->path . 'engine/tests/api/metadata.php'; + $value[] = $CONFIG->path . 'engine/tests/api/metadata_cache.php'; return $value; -}
\ No newline at end of file +} diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php index a9d28e22e..86624cd7c 100644 --- a/engine/lib/navigation.php +++ b/engine/lib/navigation.php @@ -361,6 +361,18 @@ function elgg_river_menu_setup($hook, $type, $return, $params) { $return[] = ElggMenuItem::factory($options); } } + + if (elgg_is_admin_logged_in()) { + $options = array( + 'name' => 'delete', + 'href' => elgg_add_action_tokens_to_url("action/river/delete?id=$item->id"), + 'text' => elgg_view_icon('delete'), + 'title' => elgg_echo('delete'), + 'confirm' => elgg_echo('deleteconfirm'), + 'priority' => 200, + ); + $return[] = ElggMenuItem::factory($options); + } } return $return; 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 b1245a924..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); } /** @@ -271,8 +246,8 @@ function elgg_normalize_url($url) { // '?query=test', #target return $url; - } elseif (stripos($url, 'javascript:') === 0) { - // 'javascript:' + } elseif (stripos($url, 'javascript:') === 0 || stripos($url, 'mailto:') === 0) { + // 'javascript:' and 'mailto:' // Not covered in FILTER_VALIDATE_URL return $url; @@ -310,19 +285,11 @@ function elgg_get_friendly_title($title) { return $result; } - // @todo not using this because of locale concerns - //$title = iconv('UTF-8', 'ASCII//TRANSLIT', $title); + // handle some special cases + $title = str_replace('&', 'and', $title); - // @todo this uses a utf8 character class. can use if - // we want to support utf8 in the url. - //$title = preg_replace('/[^\p{L}\- ]/u', '', $title); + $title = ElggTranslit::urlize($title); - // use A-Za-z0-9_ instead of \w because \w is locale sensitive - $title = preg_replace("/[^A-Za-z0-9_\- ]/", "", $title); - $title = str_replace(" ", "-", $title); - $title = str_replace("--", "-", $title); - $title = trim($title); - $title = elgg_strtolower($title); return $title; } @@ -392,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 * @@ -406,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. &gt; if decoded would + * create > 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 > is not decoded, but <foo> 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('>', '<', '&', '"', '''), + array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'), + $string + ); + $string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8'); + $string = str_replace( + array('&gt;', '&lt;', '&amp;', '&quot;', '&#039;'), + array('>', '<', '&', '"', '''), + $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 46c7d059e..0cf99b6fe 100644 --- a/engine/lib/pagehandler.php +++ b/engine/lib/pagehandler.php @@ -31,21 +31,24 @@ function page_handler($handler, $page) { } // return false to stop processing the request (because you handled it) - // return a new $params array if you want to route the request differently - $params = array( + // return a new $request array if you want to route the request differently + $request = array( 'handler' => $handler, 'segments' => $page, ); - $params = elgg_trigger_plugin_hook('route', $handler, NULL, $params); - if ($params === false) { + $request = elgg_trigger_plugin_hook('route', $handler, null, $request); + if ($request === false) { return true; } - $handler = $params['handler']; - $page = $params['segments']; + $handler = $request['handler']; + $page = $request['segments']; $result = false; - if (isset($CONFIG->pagehandler) && !empty($handler) && isset($CONFIG->pagehandler[$handler])) { + 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 f50c4a485..01654b1ce 100644 --- a/engine/lib/relationships.php +++ b/engine/lib/relationships.php @@ -239,6 +239,15 @@ function get_entity_relationships($guid, $inverse_relationship = FALSE) { * Also accepts all options available to elgg_get_entities() and * elgg_get_entities_from_metadata(). * + * To ask for entities that do not have a particulat relationship to an entity, + * use a custom where clause like the following: + * + * $options['wheres'][] = "NOT EXISTS ( + * SELECT 1 FROM {$db_prefix}entity_relationships + * WHERE guid_one = e.guid + * AND relationship = '$relationship' + * )"; + * * @see elgg_get_entities * @see elgg_get_entities_from_metadata * @@ -407,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 711832f70..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 */ @@ -643,9 +689,11 @@ function elgg_river_init() { elgg_register_page_handler('activity', 'elgg_river_page_handler'); $item = new ElggMenuItem('activity', elgg_echo('activity'), 'activity'); elgg_register_menu_item('site', $item); - + elgg_register_widget_type('river_widget', elgg_echo('river:widget:title'), elgg_echo('river:widget:description')); + elgg_register_action('river/delete', '', 'admin'); + elgg_register_plugin_hook_handler('unit_test', 'system', 'elgg_river_test'); } diff --git a/engine/lib/sites.php b/engine/lib/sites.php index 850092cad..d9eb2d25e 100644 --- a/engine/lib/sites.php +++ b/engine/lib/sites.php @@ -18,11 +18,19 @@ function elgg_get_site_entity($site_guid = 0) { global $CONFIG; + $result = false; + if ($site_guid == 0) { - return $CONFIG->site; + $site = $CONFIG->site; + } else { + $site = get_entity($site_guid); + } + + if($site instanceof ElggSite){ + $result = $site; } - return get_entity($site_guid); + return $result; } /** @@ -50,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/upgrades/2010121602.php b/engine/lib/upgrades/2010121602.php index 2d55c8214..5b0996b5e 100644 --- a/engine/lib/upgrades/2010121602.php +++ b/engine/lib/upgrades/2010121602.php @@ -4,7 +4,7 @@ */ $query = "UPDATE {$CONFIG->dbprefix}river - SET view='river/annotation/generic_comment/create', action_type='create' + SET view='river/annotation/generic_comment/create' WHERE view='annotation/annotate' AND action_type='comment'"; update_data($query); diff --git a/engine/lib/users.php b/engine/lib/users.php index 241b524f9..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; @@ -136,7 +137,6 @@ function ban_user($user_guid, $reason = "") { global $CONFIG; $user_guid = (int)$user_guid; - $reason = sanitise_string($reason); $user = get_entity($user_guid); diff --git a/engine/lib/views.php b/engine/lib/views.php index 25acbf2b2..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; } /** @@ -303,7 +301,7 @@ function elgg_set_view_location($view, $location, $viewtype = '') { /** * Returns whether the specified view exists * - * @note If $recurse is strue, also checks if a view exists only as an extension. + * @note If $recurse is true, also checks if a view exists only as an extension. * * @param string $view The view name * @param string $viewtype If set, forces the viewtype @@ -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,13 +1625,13 @@ 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); } } // set default icon sizes - can be overridden in settings.php or with plugin - if (!elgg_get_config('icon_sizes')) { + if (!$CONFIG->icon_sizes) { $icon_sizes = array( 'topbar' => array('w' => 16, 'h' => 16, 'square' => TRUE, 'upscale' => TRUE), 'tiny' => array('w' => 25, 'h' => 25, 'square' => TRUE, 'upscale' => TRUE), 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/start.php b/engine/start.php index 5f4bded45..55b8ffa5b 100644 --- a/engine/start.php +++ b/engine/start.php @@ -100,6 +100,15 @@ elgg_trigger_event('boot', 'system'); // Load the plugins that are active elgg_load_plugins(); + +// @todo move loading plugins into a single boot function that replaces 'boot', 'system' event +// and then move this code in there. +// This validates the view type - first opportunity to do it is after plugins load. +$view_type = elgg_get_viewtype(); +if (!elgg_is_valid_view_type($view_type)) { + elgg_set_viewtype('default'); +} + // @todo deprecate as plugins can use 'init', 'system' event elgg_trigger_event('plugins_boot', 'system'); diff --git a/engine/tests/api/metadata.php b/engine/tests/api/metadata.php index 244036f80..825290d80 100644 --- a/engine/tests/api/metadata.php +++ b/engine/tests/api/metadata.php @@ -28,6 +28,9 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest { public function testGetMetastringById() { foreach (array('metaUnitTest', 'metaunittest', 'METAUNITTEST') as $string) { + // since there is no guarantee that metastrings are garbage collected + // between unit test runs, we delete before testing + $this->delete_metastrings($string); $this->create_metastring($string); } @@ -99,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); @@ -194,11 +197,19 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest { $u2->delete(); } + protected function delete_metastrings($string) { + global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; + $METASTRINGS_CACHE = $METASTRINGS_DEADNAME_CACHE = array(); + + $string = sanitise_string($string); + mysql_query("DELETE FROM {$CONFIG->dbprefix}metastrings WHERE string = BINARY '$string'"); + } protected function create_metastring($string) { global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; $METASTRINGS_CACHE = $METASTRINGS_DEADNAME_CACHE = array(); + $string = sanitise_string($string); mysql_query("INSERT INTO {$CONFIG->dbprefix}metastrings (string) VALUES ('$string')"); $this->metastrings[$string] = mysql_insert_id(); } diff --git a/engine/tests/api/metadata_cache.php b/engine/tests/api/metadata_cache.php new file mode 100644 index 000000000..846116a7b --- /dev/null +++ b/engine/tests/api/metadata_cache.php @@ -0,0 +1,169 @@ +<?php +/** + * Elgg Test metadata cache + * + * @package Elgg + * @subpackage Test + */ +class ElggCoreMetadataCacheTest extends ElggCoreUnitTest { + + /** + * @var ElggVolatileMetadataCache + */ + protected $cache; + + /** + * @var ElggObject + */ + protected $obj1; + + /** + * @var int + */ + protected $guid1; + + /** + * @var ElggObject + */ + protected $obj2; + + /** + * @var int + */ + protected $guid2; + + protected $name = 'test'; + protected $value = 'test'; + protected $ignoreAccess; + + /** + * Called before each test method. + */ + public function setUp() { + $this->ignoreAccess = elgg_set_ignore_access(false); + + $this->cache = elgg_get_metadata_cache(); + + $this->obj1 = new ElggObject(); + $this->obj1->save(); + $this->guid1 = $this->obj1->guid; + + $this->obj2 = new ElggObject(); + $this->obj2->save(); + $this->guid2 = $this->obj2->guid; + } + + /** + * Called after each test method. + */ + public function tearDown() { + $this->obj1->delete(); + $this->obj2->delete(); + + elgg_set_ignore_access($this->ignoreAccess); + } + + public function testBasicApi() { + // test de-coupled instance + $cache = new ElggVolatileMetadataCache(); + $cache->setIgnoreAccess(false); + $guid = 1; + + $this->assertFalse($cache->isKnown($guid, $this->name)); + + $cache->markEmpty($guid, $this->name); + $this->assertTrue($cache->isKnown($guid, $this->name)); + $this->assertNull($cache->load($guid, $this->name)); + + $cache->markUnknown($guid, $this->name); + $this->assertFalse($cache->isKnown($guid, $this->name)); + + $cache->save($guid, $this->name, $this->value); + $this->assertIdentical($cache->load($guid, $this->name), $this->value); + + $cache->save($guid, $this->name, 1, true); + $this->assertIdentical($cache->load($guid, $this->name), array($this->value, 1)); + + $cache->clear($guid); + $this->assertFalse($cache->isKnown($guid, $this->name)); + } + + public function testReadsAreCached() { + // test that reads fill cache + $this->obj1->setMetaData($this->name, $this->value); + $this->cache->flush(); + + $this->obj1->getMetaData($this->name); + $this->assertIdentical($this->cache->load($this->guid1, $this->name), $this->value); + } + + public function testWritesAreCached() { + // delete should mark cache as known to be empty + $this->obj1->deleteMetadata($this->name); + $this->assertTrue($this->cache->isKnown($this->guid1, $this->name)); + $this->assertNull($this->cache->load($this->guid1, $this->name)); + + // without name, delete should invalidate the entire entity + $this->cache->save($this->guid1, $this->name, $this->value); + elgg_delete_metadata(array( + 'guid' => $this->guid1, + )); + $this->assertFalse($this->cache->isKnown($this->guid1, $this->name)); + + // test set + $this->obj1->setMetaData($this->name, $this->value); + $this->assertIdentical($this->cache->load($this->guid1, $this->name), $this->value); + + // test set multiple + $this->obj1->setMetaData($this->name, 1, 'integer', true); + $this->assertIdentical($this->cache->load($this->guid1, $this->name), array($this->value, 1)); + + // writes when access is ignore should invalidate + $tmp_ignore = elgg_set_ignore_access(true); + $this->obj1->setMetaData($this->name, $this->value); + $this->assertFalse($this->cache->isKnown($this->guid1, $this->name)); + elgg_set_ignore_access($tmp_ignore); + } + + public function testDisableAndEnable() { + // both should mark cache unknown + $this->obj1->setMetaData($this->name, $this->value); + $this->obj1->disableMetadata($this->name); + $this->assertFalse($this->cache->isKnown($this->guid1, $this->name)); + + $this->cache->save($this->guid1, $this->name, $this->value); + $this->obj1->enableMetadata($this->name); + $this->assertFalse($this->cache->isKnown($this->guid1, $this->name)); + } + + public function testPopulateFromEntities() { + // test populating cache from set of entities + $this->obj1->setMetaData($this->name, $this->value); + $this->obj1->setMetaData($this->name, 4, 'integer', true); + $this->obj1->setMetaData("{$this->name}-2", "{$this->value}-2"); + $this->obj2->setMetaData($this->name, $this->value); + + $this->cache->flush(); + $this->cache->populateFromEntities(array($this->guid1, $this->guid2)); + + $expected = array(); + $expected[$this->name][] = $this->value; + $expected[$this->name][] = 4; + $expected["{$this->name}-2"] = "{$this->value}-2"; + $this->assertIdentical($this->cache->loadAll($this->guid1), $expected); + + $expected = array(); + $expected[$this->name] = $this->value; + $this->assertIdentical($this->cache->loadAll($this->guid2), $expected); + } + + public function testFilterHeavyEntities() { + $big_str = str_repeat('-', 5000); + $this->obj2->setMetaData($this->name, array($big_str, $big_str)); + + $guids = array($this->guid1, $this->guid2); + $expected = array($this->guid1); + $actual = $this->cache->filterMetadataHeavyEntities($guids, 6000); + $this->assertIdentical($actual, $expected); + } +} 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/api/plugins.php b/engine/tests/api/plugins.php index 8ecb0a46c..114f3991b 100644 --- a/engine/tests/api/plugins.php +++ b/engine/tests/api/plugins.php @@ -68,6 +68,9 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest { 'blurb' => 'A concise description.', 'description' => 'A longer, more interesting description.', 'website' => 'http://www.elgg.org/', + 'repository' => 'https://github.com/Elgg/Elgg', + 'bugtracker' => 'http://trac.elgg.org', + 'donations' => 'http://elgg.org/supporter.php', 'copyright' => '(C) Elgg Foundation 2011', 'license' => 'GNU General Public License version 2', @@ -164,6 +167,21 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest { $this->assertEqual($this->manifest18->getWebsite(), 'http://www.elgg.org/'); $this->assertEqual($this->manifest17->getWebsite(), 'http://www.elgg.org/'); } + + public function testElggPluginManifestGetRepository() { + $this->assertEqual($this->manifest18->getRepositoryURL(), 'https://github.com/Elgg/Elgg'); + $this->assertEqual($this->manifest17->getRepositoryURL(), ''); + } + + public function testElggPluginManifestGetBugtracker() { + $this->assertEqual($this->manifest18->getBugTrackerURL(), 'http://trac.elgg.org'); + $this->assertEqual($this->manifest17->getBugTrackerURL(), ''); + } + + public function testElggPluginManifestGetDonationsPage() { + $this->assertEqual($this->manifest18->getDonationsPageURL(), 'http://elgg.org/supporter.php'); + $this->assertEqual($this->manifest17->getDonationsPageURL(), ''); + } public function testElggPluginManifestGetCopyright() { $this->assertEqual($this->manifest18->getCopyright(), '(C) Elgg Foundation 2011'); diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php index 26a45ab6a..691433a41 100644 --- a/engine/tests/regression/trac_bugs.php +++ b/engine/tests/regression/trac_bugs.php @@ -202,16 +202,33 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest { /** * http://trac.elgg.org/ticket/3210 - Don't remove -s in friendly titles - * @todo: http://trac.elgg.org/ticket/2276 - improve char encoding + * http://trac.elgg.org/ticket/2276 - improve char encoding */ public function test_friendly_title() { $cases = array( - 'Simple Test' => 'simple-test', - 'Test top-level page' => 'test-top-level-page', -// 'éclair' => 'éclair', -// 'English, Español, and 日本語' => 'english-español-and-日本語' + // hyphen, underscore and ASCII whitespace replaced by separator, + // other non-alphanumeric ASCII removed + "a-a_a a\na\ra\ta\va!a\"a#a\$a%a&a'a(a)a*a+a,a.a/a:a;a<a=a>a?a@a[a\\a]a^a`a{a|a}a~a" + => "a-a-a-a-a-a-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + + // separators trimmed + "-_ hello _-" => "hello", + + // accents removed, lower case, other multibyte chars are URL encoded + "I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n, AND \xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" + // Iñtërnâtiônàlizætiøn, AND 日本語 + => 'internationalizaetion-and-%E6%97%A5%E6%9C%AC%E8%AA%9E', + + // some HTML entity replacements + "Me & You" => 'me-and-you', ); + // where available, string is converted to NFC before transliteration + if (ElggTranslit::hasNormalizerSupport()) { + $form_d = "A\xCC\x8A"; // A followed by 'COMBINING RING ABOVE' (U+030A) + $cases[$form_d] = "a"; + } + foreach ($cases as $case => $expected) { $friendly_title = elgg_get_friendly_title($case); $this->assertIdentical($expected, $friendly_title); diff --git a/engine/tests/test_files/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 @@ +› + +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/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><?php +class DataTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provider + */ + public function testAdd($a, $b, $c) + { + $this->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&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&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><?php +class DataTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provider + */ + public function testAdd($a, $b, $c) + { + $this->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&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&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><?php +class DataTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provider + */ + public function testAdd($a, $b, $c) + { + $this->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&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&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><?php +class DataTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provider + */ + public function testAdd($a, $b, $c) + { + $this->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&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&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 › Your Profile</a></li> + <li>Start publishing at <a href="%4%24s" title="Create a new post">Posts › Add New</a> and at <a href="%5%24s" title="Create a new page">Pages › 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 › 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 › Add New Themes</a></li> + <li>Modify and prettify your website’s links at <a href="%8%24s" title="For example, select a link structure like: http://example.com/1999/12/post-name">Settings › 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 › 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 › Your Profile</a></li> + <li>Start publishing at <a href="%4$s" title="Create a new post">Posts › Add New</a> and at <a href="%5$s" title="Create a new page">Pages › 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 › 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 › Add New Themes</a></li> + <li>Modify and prettify your website’s links at <a href="%8$s" title="For example, select a link structure like: http://example.com/1999/12/post-name">Settings › 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 › 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 />≴</p> +<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></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; +≴ +<h1>h1</h1> +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> +<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/engine/tests/test_files/plugin_18/manifest.xml b/engine/tests/test_files/plugin_18/manifest.xml index 9654b6422..5d788616a 100644 --- a/engine/tests/test_files/plugin_18/manifest.xml +++ b/engine/tests/test_files/plugin_18/manifest.xml @@ -6,6 +6,9 @@ <blurb>A concise description.</blurb> <description>A longer, more interesting description.</description> <website>http://www.elgg.org/</website> + <repository>https://github.com/Elgg/Elgg</repository> + <bugtracker>http://trac.elgg.org</bugtracker> + <donations>http://elgg.org/supporter.php</donations> <copyright>(C) Elgg Foundation 2011</copyright> <license>GNU General Public License version 2</license> diff --git a/install/ElggInstaller.php b/install/ElggInstaller.php index 03c84a43e..775bbf5b6 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); } @@ -1519,22 +1519,27 @@ class ElggInstaller { protected function createAdminAccount($submissionVars, $login = FALSE) { global $CONFIG; - $guid = register_user( - $submissionVars['username'], - $submissionVars['password1'], - $submissionVars['displayname'], - $submissionVars['email'] - ); + try { + $guid = register_user( + $submissionVars['username'], + $submissionVars['password1'], + $submissionVars['displayname'], + $submissionVars['email'] + ); + } catch (Exception $e) { + register_error($e->getMessage()); + return false; + } if (!$guid) { register_error(elgg_echo('install:admin:cannot_create')); - return FALSE; + return false; } $user = get_entity($guid); if (!$user) { register_error(elgg_echo('install:error:loadadmin')); - return FALSE; + return false; } elgg_set_ignore_access(TRUE); @@ -1543,7 +1548,7 @@ class ElggInstaller { } else { datalist_set('admin_registered', 1); } - elgg_set_ignore_access(FALSE); + elgg_set_ignore_access(false); // add validation data to satisfy user validation plugins create_metadata($guid, 'validated', TRUE, '', 0, ACCESS_PUBLIC); diff --git a/install/ElggRewriteTester.php b/install/ElggRewriteTester.php index c01510f60..ab68da2b7 100644 --- a/install/ElggRewriteTester.php +++ b/install/ElggRewriteTester.php @@ -154,6 +154,8 @@ class ElggRewriteTester { if ($this->serverSupportsRemoteRead == FALSE) { $msg = elgg_echo('install:warning:rewrite:unknown', array($url)); + $msg .= elgg_view('install/js_rewrite_check', array('url' => $url)); + return array( 'severity' => 'warning', 'message' => $msg, @@ -165,6 +167,8 @@ class ElggRewriteTester { $msg = "$serverString\n\n"; if (!isset($this->htaccessIssue)) { $msg .= elgg_echo('install:error:rewrite:allowoverride'); + $msg .= elgg_view('install/js_rewrite_check', array('url' => $url)); + return array( 'severity' => 'failure', 'message' => $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/install/js/install.js b/install/js/install.js index 49b2be10c..37e5b0dc3 100644 --- a/install/js/install.js +++ b/install/js/install.js @@ -19,3 +19,24 @@ $(function() { } }); }); + +elgg = { + installer: {} +}; + +/** + * Check the rewrite address for "success" and then allows the installation to proceed. + */ +elgg.installer.rewriteTest = function(url, success_msg, nextURL) { + $.ajax(url, { + success: function(data, status, xhr) { + if (data == 'success') { + $('.elgg-require-rewrite li').attr('class', 'pass'); + $('.elgg-require-rewrite li').html('<p>' + success_msg + '</p>'); + $('.elgg-install-nav a.elgg-state-disabled') + .removeClass('elgg-state-disabled') + .attr('href', nextURL); + } + } + }); +} diff --git a/install/languages/en.php b/install/languages/en.php index 3a692e020..b2583fbc9 100644 --- a/install/languages/en.php +++ b/install/languages/en.php @@ -154,7 +154,7 @@ If you are ready to proceed, click the Next button.", 'install:error:rewrite:htaccess:cannot_copy' => 'A unknown error occurred while creating the .htaccess file. You need to manually copy htaccess_dist to .htaccess in Elgg\'s directory.', 'install:error:rewrite:altserver' => 'The rewrite rules test failed. You need to configure your web server with Elgg\'s rewrite rules and try again.', 'install:error:rewrite:unknown' => 'Oof. We couldn\'t figure out what kind of web server is running on your server and it failed the rewrite rules. We cannot offer any specific advice. Please check the troubleshooting link.', - 'install:warning:rewrite:unknown' => 'Your server does not support automatic testing of the rewrite rules. You can continue the installation, but you may experience problems with your site. You can manually test the rewrite rules by clicking this link: <a href="%s" target="_blank">test</a>. You will see the word success if the rules are working.', + 'install:warning:rewrite:unknown' => 'Your server does not support automatic testing of the rewrite rules and your browser does not support checking via JavaScript. You can continue the installation, but you may experience problems with your site. You can manually test the rewrite rules by clicking this link: <a href="%s" target="_blank">test</a>. You will see the word success if the rules are working.', ); add_translation("en", $english); diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js index 81209ebd0..dc7c07165 100644 --- a/js/lib/elgglib.js +++ b/js/lib/elgglib.js @@ -283,7 +283,7 @@ elgg.normalize_url = function(url) { } // 'javascript:' - else if (url.indexOf('javascript:') === 0) { + else if (url.indexOf('javascript:') === 0 || url.indexOf('mailto:') === 0 ) { return url; } diff --git a/js/lib/ui.js b/js/lib/ui.js index c26cbe389..2a4d269d6 100644 --- a/js/lib/ui.js +++ b/js/lib/ui.js @@ -257,7 +257,7 @@ elgg.ui.loginHandler = function(hook, type, params, options) { * @return void */ elgg.ui.initDatePicker = function() { - if ($('.elgg-input-date').length) { + var loadDatePicker = function() { $('.elgg-input-date').datepicker({ // ISO-8601 dateFormat: 'yy-mm-dd', @@ -273,9 +273,21 @@ elgg.ui.initDatePicker = function() { } } }); + }; + + if ($('.elgg-input-date').length && elgg.get_language() == 'en') { + loadDatePicker(); + } else if ($('.elgg-input-date').length) { + elgg.get({ + url: elgg.config.wwwroot + 'vendors/jquery/i18n/jquery.ui.datepicker-'+ elgg.get_language() +'.js', + dataType: "script", + cache: true, + success: loadDatePicker, + error: loadDatePicker // english language is already loaded. + }); } }; elgg.register_hook_handler('init', 'system', elgg.ui.init); elgg.register_hook_handler('init', 'system', elgg.ui.initDatePicker); -elgg.register_hook_handler('getOptions', 'ui.popup', elgg.ui.loginHandler);
\ No newline at end of file +elgg.register_hook_handler('getOptions', 'ui.popup', elgg.ui.loginHandler); diff --git a/js/lib/ui.widgets.js b/js/lib/ui.widgets.js index b7d4b2fe4..26020bb4b 100644 --- a/js/lib/ui.widgets.js +++ b/js/lib/ui.widgets.js @@ -58,6 +58,7 @@ elgg.ui.widgets.add = function(event) { handler: type, owner_guid: elgg.get_page_owner_guid(), context: $("input[name='widget_context']").val(), + show_access: $("input[name='show_access']").val(), default_widgets: $("input[name='default_widgets']").val() || 0 }, success: function(json) { 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 7cd091115..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', @@ -437,6 +438,8 @@ $english = array( 'river:ingroup' => 'in the group %s', 'river:none' => 'No activity', 'river:update' => 'Update for %s', + 'river:delete:success' => 'River item has been deleted', + 'river:delete:fail' => 'River item could not be deleted', 'river:widget:title' => "Activity", 'river:widget:description' => "Display latest activity", @@ -579,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...", @@ -686,6 +690,9 @@ $english = array( 'admin:plugins:label:categories' => 'Categories', 'admin:plugins:label:licence' => "Licence", 'admin:plugins:label:website' => "URL", + 'admin:plugins:label:repository' => "Code", + 'admin:plugins:label:bugtracker' => "Report issue", + 'admin:plugins:label:donate' => "Donate", 'admin:plugins:label:moreinfo' => 'more info', 'admin:plugins:label:version' => 'Version', 'admin:plugins:label:location' => 'Location', @@ -727,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", @@ -875,6 +883,7 @@ $english = array( 'down' => 'Down', 'top' => 'Top', 'bottom' => 'Bottom', + 'back' => 'Back', 'invite' => "Invite", diff --git a/mod/blog/actions/blog/auto_save_revision.php b/mod/blog/actions/blog/auto_save_revision.php index 66b65c5fd..e33edfaab 100644 --- a/mod/blog/actions/blog/auto_save_revision.php +++ b/mod/blog/actions/blog/auto_save_revision.php @@ -7,7 +7,7 @@ $guid = get_input('guid'); $user = elgg_get_logged_in_user_entity(); -$title = get_input('title'); +$title = htmlspecialchars(get_input('title', '', false), ENT_QUOTES, 'UTF-8'); $description = get_input('description'); $excerpt = get_input('excerpt'); diff --git a/mod/blog/actions/blog/save.php b/mod/blog/actions/blog/save.php index 8923cd0d2..070c96398 100644 --- a/mod/blog/actions/blog/save.php +++ b/mod/blog/actions/blog/save.php @@ -57,7 +57,11 @@ $required = array('title', 'description'); // load from POST and do sanity and access checking foreach ($values as $name => $default) { - $value = get_input($name, $default); + if ($name === 'title') { + $value = htmlspecialchars(get_input('title', $default, false), ENT_QUOTES, 'UTF-8'); + } else { + $value = get_input($name, $default); + } if (in_array($name, $required) && empty($value)) { $error = elgg_echo("blog:error:missing:$name"); @@ -145,7 +149,7 @@ if (!$error) { // add to river if changing status or published, regardless of new post // because we remove it for drafts. if (($new_post || $old_status == 'draft') && $status == 'published') { - add_to_river('river/object/blog/create', 'create', elgg_get_logged_in_user_guid(), $blog->getGUID()); + add_to_river('river/object/blog/create', 'create', $blog->owner_guid, $blog->getGUID()); if ($guid) { $blog->time_created = time(); @@ -170,4 +174,4 @@ if (!$error) { } else { register_error($error); forward($error_forward_url); -}
\ No newline at end of file +} diff --git a/mod/blog/lib/blog.php b/mod/blog/lib/blog.php index 9a02a8cc3..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))); @@ -272,9 +282,9 @@ function blog_get_page_content_edit($page, $guid = 0, $revision = NULL) { $vars = array(); $vars['id'] = 'blog-post-edit'; - $vars['name'] = 'blog_post'; $vars['class'] = 'elgg-form-alt'; + $sidebar = ''; if ($page == 'edit') { $blog = get_entity((int)$guid); @@ -311,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); @@ -385,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) { @@ -397,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 a805541bd..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'); @@ -125,9 +125,10 @@ $draft_warning $excerpt_input </div> -<label for="blog_description">$body_label</label> -$body_input -<br /> +<div> + <label for="blog_description">$body_label</label> + $body_input +</div> <div> <label for="blog_tags">$tags_label</label> diff --git a/mod/blog/views/default/js/blog/save_draft.php b/mod/blog/views/default/js/blog/save_draft.php index 8a994ffb0..8cd07ff5d 100644 --- a/mod/blog/views/default/js/blog/save_draft.php +++ b/mod/blog/views/default/js/blog/save_draft.php @@ -12,7 +12,7 @@ elgg.provide('elgg.blog'); */ elgg.blog.saveDraftCallback = function(data, textStatus, XHR) { if (textStatus == 'success' && data.success == true) { - var form = $('form[name=blog_post]'); + var form = $('form[id=blog-post-edit]'); // update the guid input element for new posts that now have a guid form.find('input[name=guid]').val(data.guid); @@ -36,7 +36,7 @@ elgg.blog.saveDraft = function() { } // only save on changed content - var form = $('form[name=blog_post]'); + var form = $('form[id=blog-post-edit]'); var description = form.find('textarea[name=description]').val(); var title = form.find('input[name=title]').val(); @@ -59,7 +59,7 @@ elgg.blog.saveDraft = function() { elgg.blog.init = function() { // get a copy of the body to compare for auto save - oldDescription = $('form[name=blog_post]').find('textarea[name=description]').val(); + oldDescription = $('form[id=blog-post-edit]').find('textarea[name=description]').val(); setInterval(elgg.blog.saveDraft, 60000); }; diff --git a/mod/bookmarks/actions/bookmarks/save.php b/mod/bookmarks/actions/bookmarks/save.php index 3ca6bef32..46090b115 100644 --- a/mod/bookmarks/actions/bookmarks/save.php +++ b/mod/bookmarks/actions/bookmarks/save.php @@ -5,7 +5,7 @@ * @package Bookmarks */ -$title = strip_tags(get_input('title')); +$title = htmlspecialchars(get_input('title', '', false), ENT_QUOTES, 'UTF-8'); $description = get_input('description'); $address = get_input('address'); $access_id = get_input('access_id'); diff --git a/mod/bookmarks/start.php b/mod/bookmarks/start.php index 56bac984a..66e22b565 100644 --- a/mod/bookmarks/start.php +++ b/mod/bookmarks/start.php @@ -86,8 +86,13 @@ function bookmarks_init() { * @return bool */ function bookmarks_page_handler($page) { + elgg_load_library('elgg:bookmarks'); + if (!isset($page[0])) { + $page[0] = 'all'; + } + elgg_push_breadcrumb(elgg_echo('bookmarks'), 'bookmarks/all'); // old group usernames diff --git a/mod/categories/views/default/input/categories.php b/mod/categories/views/default/input/categories.php index 75960d257..b543cde45 100644 --- a/mod/categories/views/default/input/categories.php +++ b/mod/categories/views/default/input/categories.php @@ -10,6 +10,12 @@ if (isset($vars['entity']) && $vars['entity'] instanceof ElggEntity) { $selected_categories = $vars['entity']->universal_categories; } + +// use sticky values if set +if (isset($vars['universal_categories_list'])) { + $selected_categories = $vars['universal_categories_list']; +} + $categories = elgg_get_site_entity()->categories; if (empty($categories)) { $categories = array(); diff --git a/mod/developers/manifest.xml b/mod/developers/manifest.xml index 93a12945d..e31998872 100644 --- a/mod/developers/manifest.xml +++ b/mod/developers/manifest.xml @@ -8,6 +8,7 @@ <blurb>Developer tools for Elgg</blurb> <description>A set of tools for writing plugins and themes. It is recommended that you have this plugin at the top of the plugin list.</description> <website>http://www.elgg.org/</website> + <bugtracker>http://trac.elgg.org</bugtracker> <copyright>See COPYRIGHT.txt</copyright> <license>GNU General Public License version 2</license> diff --git a/mod/developers/views/default/theme_preview/grid.php b/mod/developers/views/default/theme_preview/grid.php index 030e752e7..0c4cbb251 100644 --- a/mod/developers/views/default/theme_preview/grid.php +++ b/mod/developers/views/default/theme_preview/grid.php @@ -4,73 +4,111 @@ */ ?> -<style> -h3 {text-align: center;} -.elgg-col > .elgg-inner {border: 1px solid #cccccc; padding: 5px;} -</style> - -<div class="elgg-col elgg-col-1of5"> - <div class="elgg-inner"> - <h3>1/5</h3> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - </div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-1of1"><div class="elgg-inner"><h3>1/1</h3></div></div> </div> -<div class="elgg-col elgg-col-3of5"> - <div class="elgg-inner clearfix"> - <h3>3/5</h3> - <div class="elgg-col elgg-col-1of2"> - <div class="elgg-inner"> - <h3>1/2</h3> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - </div> - </div> - <div class="elgg-col elgg-col-1of2"> - <div class="elgg-inner"> - <h3>1/2</h3> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - </div> - </div> - <div class="elgg-col elgg-col-1of3"> - <div class="elgg-inner"> - <h3>1/3</h3> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - </div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-1of2"><div class="elgg-inner"><h3>1/2</h3></div></div> + <div class="elgg-col elgg-col-1of2"><div class="elgg-inner"><h3>1/2</h3></div></div> +</div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-1of3"><div class="elgg-inner"><h3>1/3</h3></div></div> + <div class="elgg-col elgg-col-2of3"><div class="elgg-inner"><h3>2/3</h3></div></div> +</div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-3of4"><div class="elgg-inner"><h3>3/4</h3></div></div> + <div class="elgg-col elgg-col-1of4"><div class="elgg-inner"><h3>1/4</h3></div></div> +</div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-1of5"><div class="elgg-inner"><h3>1/5</h3></div></div> + <div class="elgg-col elgg-col-4of5"><div class="elgg-inner"><h3>4/5</h3></div></div> +</div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-3of5"><div class="elgg-inner"><h3>3/5</h3></div></div> + <div class="elgg-col elgg-col-2of5"><div class="elgg-inner"><h3>2/5</h3></div></div> +</div> +<div class="elgg-grid"> + <div class="elgg-col elgg-col-1of6"><div class="elgg-inner"><h3>1/6</h3></div></div> + <div class="elgg-col elgg-col-5of6"><div class="elgg-inner"><h3>5/6</h3></div></div> +</div> +<div class="elgg-grid"> + <style> + h3 { text-align: center; } + .elgg-col > .elgg-inner { + border: 1px solid #cccccc; + border-radius: 5px; + padding: 5px; + } + </style> + <div class="elgg-col elgg-col-1of5"> + <div class="elgg-inner"> + <h3>1/5</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> - <div class="elgg-col elgg-col-2of3"> - <div class="elgg-inner"> - <h3>2/3</h3> + </div> + <div class="elgg-col elgg-col-3of5"> + <div class="elgg-inner clearfix"> + <h3>3/5</h3> + <div class="elgg-grid"> <div class="elgg-col elgg-col-1of2"> <div class="elgg-inner"> <h3>1/2</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> </div> - <div class="elgg-col elgg-col-1of2"> + <div class="elgg-col elgg-col-1of2 elgg-col-last"> <div class="elgg-inner"> <h3>1/2</h3> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> </div> - <div class="elgg-col elgg-col-1of1"> + </div> + <div class="elgg-grid"> + <div class="elgg-col elgg-col-1of3"> <div class="elgg-inner"> - <h3>1</h3> + <h3>1/3</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> </div> + <div class="elgg-col elgg-col-2of3 elgg-col-last"> + <div class="elgg-inner"> + <h3>2/3</h3> + <div class="elgg-grid"> + <div class="elgg-col elgg-col-1of2"> + <div class="elgg-inner"> + <h3>1/2</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + </div> + </div> + <div class="elgg-col elgg-col-1of2 elgg-col-last"> + <div class="elgg-inner"> + <h3>1/2</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + </div> + </div> + </div> + <div class="elgg-grid"> + <div class="elgg-col elgg-col-1of1"> + <div class="elgg-inner"> + <h3>1</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + </div> + </div> + </div> + </div> + </div> </div> </div> </div> -</div> -<div class="elgg-col elgg-col-1of5 elgg-col-last"> - <div class="elgg-inner"> - <h3>1/5</h3> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + <div class="elgg-col elgg-col-1of5 elgg-col-last"> + <div class="elgg-inner"> + <h3>1/5</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + </div> </div> </div> - -</div> diff --git a/mod/embed/start.php b/mod/embed/start.php index a3ccab66b..e8a3f8c14 100644 --- a/mod/embed/start.php +++ b/mod/embed/start.php @@ -47,7 +47,7 @@ function embed_longtext_menu($hook, $type, $items, $vars) { 'name' => 'embed', 'href' => $url, 'text' => elgg_echo('embed:media'), - 'rel' => 'lightbox', + 'rel' => "embed-lightbox-{$vars['id']}", 'link_class' => "elgg-longtext-control elgg-lightbox embed-control embed-control-{$vars['id']}", 'priority' => 10, )); diff --git a/mod/embed/views/default/js/embed/embed.php b/mod/embed/views/default/js/embed/embed.php index 0c8442292..eb6153abf 100644 --- a/mod/embed/views/default/js/embed/embed.php +++ b/mod/embed/views/default/js/embed/embed.php @@ -67,6 +67,8 @@ echo elgg_view('embed/custom_insert_js'); * @return bool */ elgg.embed.submit = function(event) { + $('.embed-wrapper .elgg-form-file-upload').hide(); + $('.embed-throbber').show(); $(this).ajaxSubmit({ dataType : 'json', @@ -82,6 +84,10 @@ elgg.embed.submit = function(event) { var url = elgg.normalize_url('embed/tab/' + forward); url = elgg.embed.addContainerGUID(url); $('.embed-wrapper').parent().load(url); + } else { + // incorrect response, presumably an error has been displayed + $('.embed-throbber').hide(); + $('.embed-wrapper .elgg-form-file-upload').show(); } } }, @@ -90,9 +96,6 @@ elgg.embed.submit = function(event) { } }); - $('.elgg-form-file-upload').hide(); - $('.embed-throbber').show(); - // this was bubbling up the DOM causing a submission event.preventDefault(); event.stopPropagation(); diff --git a/mod/externalpages/views/default/expages/wrapper.php b/mod/externalpages/views/default/expages/wrapper.php index 8eb0b2f84..c579da1ba 100644 --- a/mod/externalpages/views/default/expages/wrapper.php +++ b/mod/externalpages/views/default/expages/wrapper.php @@ -9,7 +9,7 @@ echo $vars['content']; echo '<div class="mtm">'; echo elgg_view('output/url', array( - 'text' => 'Back', + 'text' => elgg_echo('back'), 'href' => $_SERVER['HTTP_REFERER'], 'class' => 'float-alt' )); diff --git a/mod/file/actions/file/upload.php b/mod/file/actions/file/upload.php index d72d04eb7..d6dce2528 100644 --- a/mod/file/actions/file/upload.php +++ b/mod/file/actions/file/upload.php @@ -6,7 +6,7 @@ */ // Get variables -$title = get_input("title"); +$title = htmlspecialchars(get_input('title', '', false), ENT_QUOTES, 'UTF-8'); $desc = get_input("description"); $access_id = (int) get_input("access_id"); $container_guid = (int) get_input('container_guid', 0); @@ -44,7 +44,7 @@ if ($new_file) { // if no title on new upload, grab filename if (empty($title)) { - $title = $_FILES['upload']['name']; + $title = htmlspecialchars($_FILES['upload']['name'], ENT_QUOTES, 'UTF-8'); } } else { 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/discussion/save.php b/mod/groups/actions/discussion/save.php index de4afadfb..b3e9da654 100644 --- a/mod/groups/actions/discussion/save.php +++ b/mod/groups/actions/discussion/save.php @@ -4,7 +4,7 @@ */ // Get variables -$title = get_input("title"); +$title = htmlspecialchars(get_input('title', '', false), ENT_QUOTES, 'UTF-8'); $desc = get_input("description"); $status = get_input("status"); $access_id = (int) get_input("access_id"); diff --git a/mod/groups/actions/groups/edit.php b/mod/groups/actions/groups/edit.php index b513a6098..d0689be2e 100644 --- a/mod/groups/actions/groups/edit.php +++ b/mod/groups/actions/groups/edit.php @@ -5,25 +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); } // 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') { @@ -31,18 +31,23 @@ foreach ($CONFIG->group as $shortname => $valuetype) { } } -$input['name'] = get_input('name'); -$input['name'] = html_entity_decode($input['name'], ENT_COMPAT, 'UTF-8'); +$input['name'] = htmlspecialchars(get_input('name', '', false), ENT_QUOTES, 'UTF-8'); $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 ($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); } @@ -56,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 @@ -106,15 +120,22 @@ if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') { $group->save(); +// group saved so clear sticky form +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'); @@ -126,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(); + } + + $group->icontime = time(); + } +} - $thumb->setFilename($prefix."small.jpg"); - $thumb->open("write"); - $thumb->write($thumbsmall); - $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."medium.jpg"); - $thumb->open("write"); - $thumb->write($thumbmedium); - $thumb->close(); + $sizes = array('', 'tiny', 'small', 'medium', 'large'); - $thumb->setFilename($prefix."large.jpg"); - $thumb->open("write"); - $thumb->write($thumblarge); - $thumb->close(); + 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(); - $group->icontime = time(); + 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 88aeccb54..0d57f1680 100644 --- a/mod/groups/languages/en.php +++ b/mod/groups/languages/en.php @@ -12,6 +12,7 @@ $english = array( */ 'groups' => "Groups", 'groups:owned' => "Groups I own", + 'groups:owned:user' => 'Groups %s owns', 'groups:yours' => "My groups", 'groups:user' => "%s's groups", 'groups:all' => "All groups", @@ -34,12 +35,14 @@ $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', 'groups:noaccess' => 'No access to group', 'groups:permissions:error' => 'You do not have the permissions for this', 'groups:ingroup' => 'in the group', + 'groups:cantcreate' => 'You can not create a group. Only admins can.', 'groups:cantedit' => 'You can not edit this group', 'groups:saved' => 'Group saved', 'groups:featured' => 'Featured groups', @@ -258,6 +261,7 @@ or click below to view the group's join requests: 'groups:forumtopic:edited' => 'Forum topic successfully edited.', 'groups:allowhiddengroups' => 'Do you want to allow private (invisible) groups?', + 'groups:whocancreate' => 'Who can create new groups?', /** * Action messages @@ -284,4 +288,4 @@ or click below to view the group's join requests: ); -add_translation("en", $english);
\ No newline at end of file +add_translation("en", $english); diff --git a/mod/groups/lib/discussion.php b/mod/groups/lib/discussion.php index 02ab27fdc..ab2fe4849 100644 --- a/mod/groups/lib/discussion.php +++ b/mod/groups/lib/discussion.php @@ -15,7 +15,7 @@ function discussion_handle_all_page() { 'type' => 'object', 'subtype' => 'groupforumtopic', 'order_by' => 'e.last_action desc', - 'limit' => 40, + 'limit' => 20, 'full_view' => false, )); diff --git a/mod/groups/lib/groups.php b/mod/groups/lib/groups.php index 498766df0..505cacd01 100644 --- a/mod/groups/lib/groups.php +++ b/mod/groups/lib/groups.php @@ -12,7 +12,9 @@ function groups_handle_all_page() { elgg_pop_breadcrumb(); elgg_push_breadcrumb(elgg_echo('groups')); - elgg_register_title_button(); + if (elgg_get_plugin_setting('limited_groups', 'groups') != 'yes' || elgg_is_admin_logged_in()) { + elgg_register_title_button(); + } $selected_tab = get_input('filter', 'newest'); @@ -106,7 +108,11 @@ function groups_handle_owned_page() { $page_owner = elgg_get_page_owner_entity(); - $title = elgg_echo('groups:owned'); + if ($page_owner->guid == elgg_get_logged_in_user_guid()) { + $title = elgg_echo('groups:owned'); + } else { + $title = elgg_echo('groups:owned:user', array($page_owner->name)); + } elgg_push_breadcrumb($title); elgg_register_title_button(); @@ -137,7 +143,11 @@ function groups_handle_mine_page() { $page_owner = elgg_get_page_owner_entity(); - $title = elgg_echo('groups:yours'); + if ($page_owner->guid == elgg_get_logged_in_user_guid()) { + $title = elgg_echo('groups:yours'); + } else { + $title = elgg_echo('groups:user', array($page_owner->name)); + } elgg_push_breadcrumb($title); elgg_register_title_button(); @@ -176,7 +186,11 @@ function groups_handle_edit_page($page, $guid = 0) { elgg_set_page_owner_guid(elgg_get_logged_in_user_guid()); $title = elgg_echo('groups:add'); elgg_push_breadcrumb($title); - $content = elgg_view('groups/edit'); + if (elgg_get_plugin_setting('limited_groups', 'groups') != 'yes' || elgg_is_admin_logged_in()) { + $content = elgg_view('groups/edit'); + } else { + $content = elgg_echo('groups:cantcreate'); + } } else { $title = elgg_echo("groups:edit"); $group = get_entity($guid); @@ -238,6 +252,8 @@ function groups_handle_profile_page($guid) { global $autofeed; $autofeed = true; + elgg_push_context('group_profile'); + $group = get_entity($guid); if (!$group) { forward('groups/all'); @@ -481,3 +497,65 @@ function groups_register_profile_buttons($group) { } } } + +/** + * Prepares variables for the group edit form view. + * + * @param mixed $group ElggGroup or null. If a group, uses values from the group. + * @return array + */ +function groups_prepare_form_vars($group = null) { + $values = array( + 'name' => '', + 'membership' => ACCESS_PUBLIC, + 'vis' => ACCESS_PUBLIC, + 'guid' => null, + 'entity' => null + ); + + // handle customizable profile fields + $fields = elgg_get_config('group'); + + if ($fields) { + foreach ($fields as $name => $type) { + $values[$name] = ''; + } + } + + // handle tool options + $tools = elgg_get_config('group_tool_options'); + if ($tools) { + foreach ($tools as $group_option) { + $option_name = $group_option->name . "_enable"; + $values[$option_name] = $group_option->default_on ? 'yes' : 'no'; + } + } + + // get current group settings + if ($group) { + foreach (array_keys($values) as $field) { + if (isset($group->$field)) { + $values[$field] = $group->$field; + } + } + + if ($group->access_id != ACCESS_PUBLIC && $group->access_id != ACCESS_LOGGED_IN) { + // group only access - this is done to handle access not created when group is created + $values['vis'] = ACCESS_PRIVATE; + } + + $values['entity'] = $group; + } + + // get any sticky form settings + if (elgg_is_sticky_form('groups')) { + $sticky_values = elgg_get_sticky_values('groups'); + foreach ($sticky_values as $key => $value) { + $values[$key] = $value; + } + } + + elgg_clear_sticky_form('groups'); + + return $values; +} diff --git a/mod/groups/start.php b/mod/groups/start.php index 193b72a4e..9dca7dc16 100644 --- a/mod/groups/start.php +++ b/mod/groups/start.php @@ -141,35 +141,34 @@ function groups_setup_sidebar_menus() { // Get the page owner entity $page_owner = elgg_get_page_owner_entity(); - if (elgg_get_context() == 'groups') { - if ($page_owner instanceof ElggGroup) { - if (elgg_is_logged_in() && $page_owner->canEdit() && !$page_owner->isPublicMembership()) { - $url = elgg_get_site_url() . "groups/requests/{$page_owner->getGUID()}"; - elgg_register_menu_item('page', array( - 'name' => 'membership_requests', - 'text' => elgg_echo('groups:membershiprequests'), - 'href' => $url, - )); - } - } else { + if (elgg_in_context('group_profile')) { + if (elgg_is_logged_in() && $page_owner->canEdit() && !$page_owner->isPublicMembership()) { + $url = elgg_get_site_url() . "groups/requests/{$page_owner->getGUID()}"; elgg_register_menu_item('page', array( - 'name' => 'groups:all', - 'text' => elgg_echo('groups:all'), - 'href' => 'groups/all', + 'name' => 'membership_requests', + 'text' => elgg_echo('groups:membershiprequests'), + 'href' => $url, )); + } + } + if (elgg_get_context() == 'groups' && !elgg_instanceof($page_owner, 'group')) { + elgg_register_menu_item('page', array( + 'name' => 'groups:all', + 'text' => elgg_echo('groups:all'), + 'href' => 'groups/all', + )); - $user = elgg_get_logged_in_user_entity(); - if ($user) { - $url = "groups/owner/$user->username"; - $item = new ElggMenuItem('groups:owned', elgg_echo('groups:owned'), $url); - elgg_register_menu_item('page', $item); - $url = "groups/member/$user->username"; - $item = new ElggMenuItem('groups:member', elgg_echo('groups:yours'), $url); - elgg_register_menu_item('page', $item); - $url = "groups/invitations/$user->username"; - $item = new ElggMenuItem('groups:user:invites', elgg_echo('groups:invitations'), $url); - elgg_register_menu_item('page', $item); - } + $user = elgg_get_logged_in_user_entity(); + if ($user) { + $url = "groups/owner/$user->username"; + $item = new ElggMenuItem('groups:owned', elgg_echo('groups:owned'), $url); + elgg_register_menu_item('page', $item); + $url = "groups/member/$user->username"; + $item = new ElggMenuItem('groups:member', elgg_echo('groups:yours'), $url); + elgg_register_menu_item('page', $item); + $url = "groups/invitations/$user->username"; + $item = new ElggMenuItem('groups:user:invites', elgg_echo('groups:invitations'), $url); + elgg_register_menu_item('page', $item); } } } @@ -195,8 +194,21 @@ function groups_setup_sidebar_menus() { */ function groups_page_handler($page) { + // forward old profile urls + if (is_numeric($page[0])) { + $group = get_entity($page[0]); + if (elgg_instanceof($group, 'group', '', 'ElggGroup')) { + system_message(elgg_echo('changebookmark')); + forward($group->getURL()); + } + } + elgg_load_library('elgg:groups'); + if (!isset($page[0])) { + $page[0] = 'all'; + } + elgg_push_breadcrumb(elgg_echo('groups'), "groups/all"); switch ($page[0]) { @@ -786,6 +798,10 @@ function discussion_page_handler($page) { elgg_load_library('elgg:discussion'); + if (!isset($page[0])) { + $page[0] = 'all'; + } + elgg_push_breadcrumb(elgg_echo('discussion'), 'discussion/all'); switch ($page[0]) { diff --git a/mod/groups/views/default/forms/groups/edit.php b/mod/groups/views/default/forms/groups/edit.php index 8055b6430..41d97e6c3 100644 --- a/mod/groups/views/default/forms/groups/edit.php +++ b/mod/groups/views/default/forms/groups/edit.php @@ -5,18 +5,9 @@ * @package ElggGroups */ -// new groups default to open membership -if (isset($vars['entity'])) { - $membership = $vars['entity']->membership; - $access = $vars['entity']->access_id; - if ($access != ACCESS_PUBLIC && $access != ACCESS_LOGGED_IN) { - // group only - this is done to handle access not created when group is created - $access = ACCESS_PRIVATE; - } -} else { - $membership = ACCESS_PUBLIC; - $access = ACCESS_PUBLIC; -} +// only extract these elements. +$name = $membership = $vis = $entity = null; +extract($vars, EXTR_IF_EXISTS); ?> <div> @@ -27,7 +18,7 @@ if (isset($vars['entity'])) { <label><?php echo elgg_echo("groups:name"); ?></label><br /> <?php echo elgg_view("input/text", array( 'name' => 'name', - 'value' => $vars['entity']->name, + 'value' => $name )); ?> </div> @@ -45,7 +36,7 @@ if ($group_profile_fields > 0) { echo "</label>$line_break"; echo elgg_view("input/{$valtype}", array( 'name' => $shortname, - 'value' => $vars['entity']->$shortname, + 'value' => elgg_extract($shortname, $vars) )); echo '</div>'; } @@ -70,10 +61,6 @@ if ($group_profile_fields > 0) { <?php if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') { - $this_owner = $vars['entity']->owner_guid; - if (!$this_owner) { - $this_owner = elgg_get_logged_in_user_guid(); - } $access_options = array( ACCESS_PRIVATE => elgg_echo('groups:access:group'), ACCESS_LOGGED_IN => elgg_echo("LOGGED_IN"), @@ -86,7 +73,7 @@ if (elgg_get_plugin_setting('hidden_groups', 'groups') == 'yes') { <?php echo elgg_echo('groups:visibility'); ?><br /> <?php echo elgg_view('input/access', array( 'name' => 'vis', - 'value' => $access, + 'value' => $vis, 'options_values' => $access_options, )); ?> @@ -96,17 +83,48 @@ 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);')); foreach ($tools 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'; - } - $value = $vars['entity']->$group_option_toggle_name ? $vars['entity']->$group_option_toggle_name : $group_option_default_value; + $value = elgg_extract($group_option_toggle_name, $vars); ?> <div> <label> @@ -129,17 +147,17 @@ if ($tools) { <div class="elgg-foot"> <?php -if (isset($vars['entity'])) { +if ($entity) { echo elgg_view('input/hidden', array( 'name' => 'group_guid', - 'value' => $vars['entity']->getGUID(), + 'value' => $entity->getGUID(), )); } echo elgg_view('input/submit', array('value' => elgg_echo('save'))); -if (isset($vars['entity'])) { - $delete_url = 'action/groups/delete?guid=' . $vars['entity']->getGUID(); +if ($entity) { + $delete_url = 'action/groups/delete?guid=' . $entity->getGUID(); echo elgg_view('output/confirmlink', array( 'text' => elgg_echo('groups:delete'), 'href' => $delete_url, diff --git a/mod/groups/views/default/groups/edit.php b/mod/groups/views/default/groups/edit.php index 24a1c3f1e..5579ad54a 100644 --- a/mod/groups/views/default/groups/edit.php +++ b/mod/groups/views/default/groups/edit.php @@ -11,5 +11,5 @@ $form_vars = array( 'enctype' => 'multipart/form-data', 'class' => 'elgg-form-alt', ); -$body_vars = array('entity' => $entity); -echo elgg_view_form('groups/edit', $form_vars, $body_vars); + +echo elgg_view_form('groups/edit', $form_vars, groups_prepare_form_vars($entity)); 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/default/plugins/groups/settings.php b/mod/groups/views/default/plugins/groups/settings.php index 7197dcb37..41ea146db 100644 --- a/mod/groups/views/default/plugins/groups/settings.php +++ b/mod/groups/views/default/plugins/groups/settings.php @@ -8,6 +8,11 @@ if (!isset($vars['entity']->hidden_groups)) { $vars['entity']->hidden_groups = 'no'; } +// set default value +if (!isset($vars['entity']->limited_groups)) { + $vars['entity']->limited_groups = 'no'; +} + echo '<div>'; echo elgg_echo('groups:allowhiddengroups'); echo ' '; @@ -20,3 +25,16 @@ echo elgg_view('input/dropdown', array( 'value' => $vars['entity']->hidden_groups, )); echo '</div>'; + +echo '<div>'; +echo elgg_echo('groups:whocancreate'); +echo ' '; +echo elgg_view('input/dropdown', array( + 'name' => 'params[limited_groups]', + 'options_values' => array( + 'no' => elgg_echo('LOGGED_IN'), + 'yes' => elgg_echo('admin') + ), + 'value' => $vars['entity']->limited_groups, +)); +echo '</div>'; 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/htmlawed/start.php b/mod/htmlawed/start.php index 10bea2a52..12b6470a3 100644 --- a/mod/htmlawed/start.php +++ b/mod/htmlawed/start.php @@ -18,6 +18,8 @@ function htmlawed_init() { $lib = elgg_get_plugins_path() . "htmlawed/vendors/htmLawed/htmLawed.php"; elgg_register_library('htmlawed', $lib); + + elgg_register_plugin_hook_handler('unit_test', 'system', 'htmlawed_test'); } /** @@ -90,7 +92,13 @@ function htmLawedArray(&$v, $k, $htmlawed_config) { * @param array $attributes An array of attributes * @return string */ -function htmlawed_tag_post_processor($element, $attributes) { +function htmlawed_tag_post_processor($element, $attributes = false) { + if ($attributes === false) { + // This is a closing tag. Prevent further processing to avoid inserting a duplicate tag + + return "</${element}>"; + } + // these are the default styles used by tinymce. $allowed_styles = array( 'color', 'cursor', 'text-align', 'vertical-align', 'font-size', @@ -143,3 +151,15 @@ function htmlawed_tag_post_processor($element, $attributes) { $r = "<$element$string>"; return $r; } + +/** + * Runs unit tests for htmlawed + * + * @return array + * */ +function htmlawed_test($hook, $type, $value, $params) { + global $CONFIG; + + $value[] = dirname(__FILE__) . '/tests/tags.php'; + return $value; +} diff --git a/mod/htmlawed/tests/tags.php b/mod/htmlawed/tests/tags.php new file mode 100644 index 000000000..b3914a9d6 --- /dev/null +++ b/mod/htmlawed/tests/tags.php @@ -0,0 +1,45 @@ +<?php +/** + * Dupplicated tags in htmlawed + */ +class HtmLawedDuplicateTagsTest extends ElggCoreUnitTest { + + /** + * Called before each test object. + */ + public function __construct() { + parent::__construct(); + } + + /** + * Called before each test method. + */ + public function setUp() { + } + + /** + * Called after each test method. + */ + public function tearDown() { + // do not allow SimpleTest to interpret Elgg notices as exceptions + $this->swallowErrors(); + } + + /** + * Called after each test object. + */ + public function __destruct() { + elgg_set_ignore_access($this->ia); + // all __destruct() code should go above here + parent::__destruct(); + } + + public function testNotDuplicateTags() { + $filter_html = '<ul><li>item</li></ul>'; + set_input('test', $filter_html); + + $expected = $filter_html; + $result = get_input('test'); + $this->assertEqual($result, $expected); + } +}
\ No newline at end of file diff --git a/mod/likes/actions/likes/delete.php b/mod/likes/actions/likes/delete.php index 88cb84467..322d512e8 100644 --- a/mod/likes/actions/likes/delete.php +++ b/mod/likes/actions/likes/delete.php @@ -4,8 +4,23 @@ * */ +// Support deleting by id in case we're deleting another user's likes $id = (int) get_input('id'); -$like = elgg_get_annotation_from_id($id); + +$like = NULL; +if ($id) { + $like = elgg_get_annotation_from_id($id); +} + +if (!$like) { + $likes = elgg_get_annotations(array( + 'guid' => (int) get_input('guid'), + 'annotation_owner_guid' => elgg_get_logged_in_user_guid(), + 'annotation_name' => 'likes', + )); + $like = $likes[0]; +} + if ($like && $like->canEdit()) { $like->delete(); system_message(elgg_echo("likes:deleted")); diff --git a/mod/likes/languages/en.php b/mod/likes/languages/en.php index b9460aa10..bdbd2a963 100644 --- a/mod/likes/languages/en.php +++ b/mod/likes/languages/en.php @@ -17,7 +17,7 @@ $english = array( 'likes:userlikedthis' => '%s like', 'likes:userslikedthis' => '%s likes', 'likes:river:annotate' => 'likes', - 'likes:delete:confirm' => 'Are you sure you want to unlike this?', + 'likes:delete:confirm' => 'Are you sure you want to delete this like?', 'river:likes' => 'likes %s %s', diff --git a/mod/likes/views/default/annotation/likes.php b/mod/likes/views/default/annotation/likes.php index abd4df823..2b5acc520 100644 --- a/mod/likes/views/default/annotation/likes.php +++ b/mod/likes/views/default/annotation/likes.php @@ -29,11 +29,11 @@ $friendlytime = elgg_view_friendly_time($like->time_created); if ($like->canEdit()) { $delete_button = elgg_view("output/confirmlink",array( - 'href' => "action/likes/delete?id={$like->id}", - 'text' => "<span class=\"elgg-icon elgg-icon-delete float-alt\"></span>", - 'confirm' => elgg_echo('likes:delete:confirm'), - 'encode_text' => false, - )); + 'href' => "action/likes/delete?id={$like->id}", + 'text' => "<span class=\"elgg-icon elgg-icon-delete float-alt\"></span>", + 'confirm' => elgg_echo('likes:delete:confirm'), + 'encode_text' => false, + )); } $body = <<<HTML diff --git a/mod/likes/views/default/likes/button.php b/mod/likes/views/default/likes/button.php index 956bbcb19..bc7c8fd8a 100644 --- a/mod/likes/views/default/likes/button.php +++ b/mod/likes/views/default/likes/button.php @@ -24,13 +24,7 @@ if (elgg_is_logged_in() && $vars['entity']->canAnnotate(0, 'likes')) { ); $likes_button = elgg_view('output/url', $params); } else { - $like = elgg_get_annotations(array( - 'guid' => $guid, - 'annotation_owner_guid' => elgg_get_logged_in_user_guid(), - 'annotation_name' => 'likes', - )); - $like = $like[0]; - $url = elgg_get_site_url() . "action/likes/delete?id={$like->id}"; + $url = elgg_get_site_url() . "action/likes/delete?guid={$guid}"; $params = array( 'href' => $url, 'text' => elgg_view_icon('thumbs-up-alt'), 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/manifest.xml b/mod/messages/manifest.xml index 73a58d9d4..6e3462901 100644 --- a/mod/messages/manifest.xml +++ b/mod/messages/manifest.xml @@ -6,8 +6,8 @@ <category>bundled</category> <category>communication</category> <description>Elgg internal messages plugin. This plugin lets user send each other messages.</description> - <copyright>See COPYRIGHT.txt</copyright> <website>http://www.elgg.org/</website> + <copyright>See COPYRIGHT.txt</copyright> <license>GNU General Public License version 2</license> <requires> <type>elgg_release</type> diff --git a/mod/messages/pages/messages/inbox.php b/mod/messages/pages/messages/inbox.php index fdfc20c43..de5b8b231 100644 --- a/mod/messages/pages/messages/inbox.php +++ b/mod/messages/pages/messages/inbox.php @@ -8,8 +8,13 @@ gatekeeper(); $page_owner = elgg_get_page_owner_entity(); -if (!$page_owner) { - register_error(elgg_echo()); + +if (!$page_owner || !$page_owner->canEdit()) { + $guid = 0; + if($page_owner){ + $guid = $page_owner->getGUID(); + } + register_error(elgg_echo("pageownerunavailable", array($guid))); forward(); } diff --git a/mod/messages/pages/messages/read.php b/mod/messages/pages/messages/read.php index 19e3ecdd7..4223c6bac 100644 --- a/mod/messages/pages/messages/read.php +++ b/mod/messages/pages/messages/read.php @@ -8,8 +8,8 @@ gatekeeper(); $message = get_entity(get_input('guid')); -if (!$message) { - forward('messages/inbox'); +if (!$message || !elgg_instanceof($message, "object", "messages")) { + forward('messages/inbox/' . elgg_get_logged_in_user_entity()->username); } // mark the message as read @@ -38,8 +38,9 @@ if ($inbox) { ); $body_params = array('message' => $message); $content .= elgg_view_form('messages/reply', $form_params, $body_params); - - if (elgg_get_logged_in_user_guid() == elgg_get_page_owner_guid()) { + $from_user = get_user($message->fromId); + + 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/messages/pages/messages/sent.php b/mod/messages/pages/messages/sent.php index af06ab273..3d08cd5ee 100644 --- a/mod/messages/pages/messages/sent.php +++ b/mod/messages/pages/messages/sent.php @@ -8,8 +8,13 @@ gatekeeper(); $page_owner = elgg_get_page_owner_entity(); -if (!$page_owner) { - register_error(elgg_echo()); + +if (!$page_owner || !$page_owner->canEdit()) { + $guid = 0; + if($page_owner){ + $guid = $page_owner->getGUID(); + } + register_error(elgg_echo("pageownerunavailable", array($guid))); forward(); } diff --git a/mod/pages/actions/pages/edit.php b/mod/pages/actions/pages/edit.php index a32e4a4ba..40215e02e 100644 --- a/mod/pages/actions/pages/edit.php +++ b/mod/pages/actions/pages/edit.php @@ -8,9 +8,10 @@ $variables = elgg_get_config('pages'); $input = array(); foreach ($variables as $name => $type) { - $input[$name] = get_input($name); if ($name == 'title') { - $input[$name] = strip_tags($input[$name]); + $input[$name] = htmlspecialchars(get_input($name, '', false), ENT_QUOTES, 'UTF-8'); + } else { + $input[$name] = get_input($name); } if ($type == 'tags') { $input[$name] = string_to_tag_array($input[$name]); @@ -59,6 +60,9 @@ if (sizeof($input) > 0) { if (($name == 'access_id' || $name == 'write_access_id') && !$can_change_access) { continue; } + if ($name == 'parent_guid') { + continue; + } $page->$name = $value; } @@ -67,7 +71,27 @@ if (sizeof($input) > 0) { // need to add check to make sure user can write to container $page->container_guid = $container_guid; -if ($parent_guid) { +if ($parent_guid && $parent_guid != $page_guid) { + // Check if parent isn't below the page in the tree + if ($page_guid) { + $tree_page = get_entity($parent_guid); + while ($tree_page->parent_guid > 0 && $page_guid != $tree_page->guid) { + $tree_page = get_entity($tree_page->parent_guid); + } + // If is below, bring all child elements forward + if ($page_guid == $tree_page->guid) { + $previous_parent = $page->parent_guid; + $children = elgg_get_entities_from_metadata(array( + 'metadata_name' => 'parent_guid', + 'metadata_value' => $page->getGUID() + )); + if ($children) { + foreach ($children as $child) { + $child->parent_guid = $previous_parent; + } + } + } + } $page->parent_guid = $parent_guid; } diff --git a/mod/pages/languages/en.php b/mod/pages/languages/en.php index eb9d22708..930676b3e 100644 --- a/mod/pages/languages/en.php +++ b/mod/pages/languages/en.php @@ -61,6 +61,7 @@ View and comment on the new page: 'pages:title' => 'Page title', 'pages:description' => 'Page text', 'pages:tags' => 'Tags', + 'pages:parent_guid' => 'Parent page', 'pages:access_id' => 'Read access', 'pages:write_access_id' => 'Write access', @@ -110,4 +111,4 @@ View and comment on the new page: 'pages:backtoparent' => "Back to '%s'", ); -add_translation("en", $english);
\ No newline at end of file +add_translation("en", $english); diff --git a/mod/pages/lib/pages.php b/mod/pages/lib/pages.php index 3f27118a6..afe42b68f 100644 --- a/mod/pages/lib/pages.php +++ b/mod/pages/lib/pages.php @@ -65,11 +65,11 @@ function pages_prepare_parent_breadcrumbs($page) { } /** - * Register the navigation menu + * Produce the navigation tree * * @param ElggEntity $container Container entity for the pages */ -function pages_register_navigation_tree($container) { +function pages_get_navigation_tree($container) { if (!$container) { return; } @@ -84,13 +84,18 @@ function pages_register_navigation_tree($container) { if (!$top_pages) { return; } + + $tree = array(); + $depths = array(); foreach ($top_pages as $page) { - elgg_register_menu_item('pages_nav', array( - 'name' => $page->getGUID(), - 'text' => $page->title, - 'href' => $page->getURL(), - )); + $tree[] = array( + 'guid' => $page->getGUID(), + 'title' => $page->title, + 'url' => $page->getURL(), + 'depth' => 0, + ); + $depths[$page->guid] = 0; $stack = array(); array_push($stack, $page); @@ -103,16 +108,40 @@ function pages_register_navigation_tree($container) { 'metadata_value' => $parent->getGUID(), 'limit' => 0, )); - - foreach ($children as $child) { - elgg_register_menu_item('pages_nav', array( - 'name' => $child->getGUID(), - 'text' => $child->title, - 'href' => $child->getURL(), - 'parent_name' => $parent->getGUID(), - )); - array_push($stack, $child); + + if ($children) { + foreach ($children as $child) { + $tree[] = array( + 'guid' => $child->getGUID(), + 'title' => $child->title, + 'url' => $child->getURL(), + 'parent_guid' => $parent->getGUID(), + 'depth' => $depths[$parent->guid] + 1, + ); + $depths[$child->guid] = $depths[$parent->guid] + 1; + array_push($stack, $child); + } } } } -}
\ No newline at end of file + return $tree; +} + +/** + * Register the navigation menu + * + * @param ElggEntity $container Container entity for the pages + */ +function pages_register_navigation_tree($container) { + $pages = pages_get_navigation_tree($container); + if ($pages) { + foreach ($pages as $page) { + elgg_register_menu_item('pages_nav', array( + 'name' => $page['guid'], + 'text' => $page['title'], + 'href' => $page['url'], + 'parent_name' => $page['parent_guid'], + )); + } + } +} diff --git a/mod/pages/start.php b/mod/pages/start.php index c385131bd..6d974f122 100644 --- a/mod/pages/start.php +++ b/mod/pages/start.php @@ -30,7 +30,6 @@ function pages_init() { // Register some actions $action_base = elgg_get_plugins_path() . 'pages/actions/pages'; elgg_register_action("pages/edit", "$action_base/edit.php"); - elgg_register_action("pages/editwelcome", "$action_base/editwelcome.php"); elgg_register_action("pages/delete", "$action_base/delete.php"); // Extend the main css view @@ -64,6 +63,7 @@ function pages_init() { 'title' => 'text', 'description' => 'longtext', 'tags' => 'tags', + 'parent_guid' => 'parent', 'access_id' => 'access', 'write_access_id' => 'write_access', )); diff --git a/mod/pages/views/default/forms/pages/edit.php b/mod/pages/views/default/forms/pages/edit.php index 9469f5eb9..e14ff19ec 100644 --- a/mod/pages/views/default/forms/pages/edit.php +++ b/mod/pages/views/default/forms/pages/edit.php @@ -18,6 +18,18 @@ foreach ($variables as $name => $type) { if (($type == 'access' || $type == 'write_access') && !$can_change_access) { continue; } + + // don't show parent picker input for top or new pages. + if ($name == 'parent_guid' && (!$vars['parent_guid'] || !$vars['guid'])) { + continue; + } + + if ($type == 'parent') { + $input_view = "pages/input/$type"; + } else { + $input_view = "input/$type"; + } + ?> <div> <label><?php echo elgg_echo("pages:$name") ?></label> @@ -26,9 +38,10 @@ foreach ($variables as $name => $type) { echo '<br />'; } - echo elgg_view("input/$type", array( + echo elgg_view($input_view, array( 'name' => $name, 'value' => $vars[$name], + 'entity' => ($name == 'parent_guid') ? $vars['entity'] : null, )); ?> </div> @@ -52,7 +65,7 @@ echo elgg_view('input/hidden', array( 'name' => 'container_guid', 'value' => $vars['container_guid'], )); -if ($vars['parent_guid']) { +if (!$vars['guid']) { echo elgg_view('input/hidden', array( 'name' => 'parent_guid', 'value' => $vars['parent_guid'], diff --git a/mod/pages/views/default/pages/icon.php b/mod/pages/views/default/pages/icon.php index d3b749eb8..cba034ec4 100644 --- a/mod/pages/views/default/pages/icon.php +++ b/mod/pages/views/default/pages/icon.php @@ -21,5 +21,5 @@ if (!in_array($vars['size'], array('small', 'medium', 'large', 'tiny', 'master', ?> <a href="<?php echo $annotation->getURL(); ?>"> - <img src="<?php echo $entity->getIconURL($vars['size']); ?>" /> + <img alt="<?php echo $entity->title; ?>" src="<?php echo $entity->getIconURL($vars['size']); ?>" /> </a> diff --git a/mod/pages/views/default/pages/input/parent.php b/mod/pages/views/default/pages/input/parent.php new file mode 100644 index 000000000..c5ee3c3fb --- /dev/null +++ b/mod/pages/views/default/pages/input/parent.php @@ -0,0 +1,37 @@ +<?php +/** + * Parent picker + * + * @uses $vars['value'] The current value, if any + * @uses $vars['options_values'] + * @uses $vars['name'] The name of the input field + * @uses $vars['entity'] Optional. The child entity (uses container_guid) + */ + +elgg_load_library('elgg:pages'); + +if (empty($vars['entity'])) { + $container = elgg_get_page_owner_entity(); +} else { + $container = $vars['entity']->getContainerEntity(); +} + +$pages = pages_get_navigation_tree($container); +$options = array(); + +foreach ($pages as $page) { + $spacing = ""; + for ($i = 0; $i < $page['depth']; $i++) { + $spacing .= "--"; + } + $options[$page['guid']] = "$spacing " . $page['title']; +} + +$defaults = array( + 'class' => 'elgg-pages-input-parent-picker', + 'options_values' => $options, +); + +$vars = array_merge($defaults, $vars); + +echo elgg_view('input/dropdown', $vars); diff --git a/mod/profile/icondirect.php b/mod/profile/icondirect.php index 6c3148f2b..dbab5d31f 100644 --- a/mod/profile/icondirect.php +++ b/mod/profile/icondirect.php @@ -11,13 +11,19 @@ require_once(dirname(dirname(dirname(__FILE__))). '/engine/settings.php'); global $CONFIG; +// won't be able to serve anything if no joindate or guid +if (!isset($_GET['joindate']) || !isset($_GET['guid'])) { + header("HTTP/1.1 404 Not Found"); + exit; +} + $join_date = (int)$_GET['joindate']; $last_cache = (int)$_GET['lastcache']; // icontime $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; } @@ -49,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/start.php b/mod/profile/start.php index abe044632..ab596f235 100644 --- a/mod/profile/start.php +++ b/mod/profile/start.php @@ -56,6 +56,8 @@ function profile_page_handler($page) { $username = $page[0]; $user = get_user_by_username($username); elgg_set_page_owner_guid($user->guid); + } elseif (elgg_is_logged_in()) { + forward(elgg_get_logged_in_user_entity()->getURL()); } // short circuit if invalid or banned username 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/reportedcontent/views/default/widgets/reportedcontent/content.php b/mod/reportedcontent/views/default/widgets/reportedcontent/content.php index 4f8906ef2..4c6595653 100644 --- a/mod/reportedcontent/views/default/widgets/reportedcontent/content.php +++ b/mod/reportedcontent/views/default/widgets/reportedcontent/content.php @@ -7,6 +7,7 @@ $list = elgg_list_entities(array( 'types' => 'object', 'subtypes' => 'reported_content', 'limit' => $vars['entity']->num_display, + 'pagination' => false, )); if (!$list) { $list = '<p class="mtm">' . elgg_echo('reportedcontent:none') . '</p>'; diff --git a/mod/search/start.php b/mod/search/start.php index d2d7ed3c2..f493508d8 100644 --- a/mod/search/start.php +++ b/mod/search/start.php @@ -94,6 +94,8 @@ function search_get_highlighted_relevant_substrings($haystack, $query, $min_matc if (!$tag_match) { $words = search_remove_ignored_words($query, 'array'); + } else { + $words = array(); } // if haystack < $max_length return the entire haystack w/formatting immediately @@ -142,7 +144,7 @@ function search_get_highlighted_relevant_substrings($haystack, $query, $min_matc $total_length = array_sum($offsets); $add_length = 0; - if ($total_length < $max_length) { + if ($total_length < $max_length && $offsets) { $add_length = floor((($max_length - $total_length) / count($offsets)) / 2); $starts = array(); 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/search/views/default/search/search_box.php b/mod/search/views/default/search/search_box.php index ff12ae4f0..7474a280c 100644 --- a/mod/search/views/default/search/search_box.php +++ b/mod/search/views/default/search/search_box.php @@ -32,12 +32,11 @@ if (function_exists('mb_convert_encoding')) { } $display_query = htmlspecialchars($display_query, ENT_QUOTES, 'UTF-8', false); - ?> <form class="<?php echo $class; ?>" action="<?php echo elgg_get_site_url(); ?>search" method="get"> <fieldset> - <input type="text" class="search-input" size="21" name="q" value="<?php echo elgg_echo('search'); ?>" onblur="if (this.value=='') { this.value='<?php echo elgg_echo('search'); ?>' }" onfocus="if (this.value=='<?php echo elgg_echo('search'); ?>') { this.value='' };" /> + <input type="text" class="search-input" size="21" name="q" value="<?php echo $display_query; ?>" onblur="if (this.value=='') { this.value='<?php echo elgg_echo('search'); ?>' }" onfocus="if (this.value=='<?php echo elgg_echo('search'); ?>') { this.value='' };" /> <input type="hidden" name="search_type" value="all" /> <input type="submit" value="<?php echo elgg_echo('search:go'); ?>" class="search-submit-button" /> </fieldset> diff --git a/mod/thewire/actions/delete.php b/mod/thewire/actions/delete.php index 58502a7e7..38355d25e 100644 --- a/mod/thewire/actions/delete.php +++ b/mod/thewire/actions/delete.php @@ -24,7 +24,7 @@ if ($thewire->getSubtype() == "thewire" && $thewire->canEdit()) { } // Get owning user - $owner = get_entity($thewire->getOwner()); + $owner = get_entity($thewire->getOwnerGUID()); // Delete it $rowsaffected = $thewire->delete(); diff --git a/mod/thewire/views/default/js/thewire.php b/mod/thewire/views/default/js/thewire.php index 0a6eba134..ba8f35050 100644 --- a/mod/thewire/views/default/js/thewire.php +++ b/mod/thewire/views/default/js/thewire.php @@ -34,11 +34,11 @@ elgg.thewire.textCounter = function(textarea, status, limit) { status.html(remaining_chars); if (remaining_chars < 0) { - status.parent().css("color", "#D40D12"); + status.parent().addClass("thewire-characters-remaining-warning"); $("#thewire-submit-button").attr('disabled', 'disabled'); $("#thewire-submit-button").addClass('elgg-state-disabled'); } else { - status.parent().css("color", ""); + status.parent().removeClass("thewire-characters-remaining-warning"); $("#thewire-submit-button").removeAttr('disabled', 'disabled'); $("#thewire-submit-button").removeClass('elgg-state-disabled'); } @@ -57,16 +57,16 @@ elgg.thewire.viewPrevious = function(event) { var postGuid = $link.attr("href").split("/").pop(); var $previousDiv = $("#thewire-previous-" + postGuid); - if ($link.html() == "<?php echo elgg_echo('thewire:hide'); ?>") { - $link.html("<?php echo elgg_echo('thewire:previous'); ?>"); - $link.attr("title", "<?php echo elgg_echo('thewire:previous:help'); ?>"); + if ($link.html() == elgg.echo('thewire:hide')) { + $link.html(elgg.echo('thewire:previous')); + $link.attr("title", elgg.echo('thewire:previous:help')); $previousDiv.slideUp(400); } else { - $link.html("<?php echo elgg_echo('thewire:hide'); ?>"); - $link.attr("title", "<?php echo elgg_echo('thewire:hide:help'); ?>"); + $link.html(elgg.echo('thewire:hide')); + $link.attr("title", elgg.echo('thewire:hide:help')); $.ajax({type: "GET", - url: "<?php echo $site_url . "ajax/view/thewire/previous"; ?>", + url: elgg.config.wwwroot + "ajax/view/thewire/previous", dataType: "html", cache: false, data: {guid: postGuid}, diff --git a/mod/thewire/views/default/thewire/css.php b/mod/thewire/views/default/thewire/css.php index d1ef31993..d11cce74a 100644 --- a/mod/thewire/views/default/thewire/css.php +++ b/mod/thewire/views/default/thewire/css.php @@ -27,6 +27,9 @@ The Wire text-align: right; background: white; } +.thewire-characters-remaining-warning { + color: #D40D12 !important; +} .thewire-parent { margin-left: 40px; } 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/tinymce/README.txt b/mod/tinymce/README.txt new file mode 100644 index 000000000..2814e9390 --- /dev/null +++ b/mod/tinymce/README.txt @@ -0,0 +1,10 @@ +Adding a language +====================== +1. Download the language pack from [TinyMCE][1] +2. Extract the files from the zip file. +3. Copy the langs, plugins, and themes directories into mod/tinymce/vendor/tinymce/jscripts/tiny_mce/. +There are already directories with those names. You do not want to delete those directories. +Instead, copy the new directories on top of the old ones. +4. Flush the Elgg caches. + +[1]: http://www.tinymce.com/i18n/index.php?ctrl=lang&act=download "TinyMCE" diff --git a/mod/tinymce/activate.php b/mod/tinymce/activate.php new file mode 100644 index 000000000..6f5cc8d50 --- /dev/null +++ b/mod/tinymce/activate.php @@ -0,0 +1,14 @@ +<?php +/** + * Prompt the user to install a tinymce language after activating + */ + +if (elgg_get_config('language') != tinymce_get_site_language()) { + $message = elgg_echo('tinymce:lang_notice', array( + elgg_echo(elgg_get_config('language')), + "http://www.tinymce.com/i18n/index.php?ctrl=lang&act=download", + elgg_get_plugins_path() . "tinymce/vendor/tinymce/jscripts/tiny_mce/", + elgg_add_action_tokens_to_url(elgg_normalize_url('action/admin/site/flush_cache')), + )); + elgg_add_admin_notice('tinymce_admin_notice_no_lang', $message); +} diff --git a/mod/tinymce/languages/en.php b/mod/tinymce/languages/en.php index 811e93492..b2702549c 100644 --- a/mod/tinymce/languages/en.php +++ b/mod/tinymce/languages/en.php @@ -9,6 +9,7 @@ $english = array( 'tinymce:remove' => "Remove editor", 'tinymce:add' => "Add editor", 'tinymce:word_count' => 'Word count: ', + 'tinymce:lang_notice' => "Your site language is %s but it isn't installed for TinyMCE. Get it <a target=\"_blank\" href=\"%s\">here</a> and copy it to %s. Then, <a href=\"%s\">flush the caches</a>. See the TinyMCE README for more details.", ); -add_translation("en", $english);
\ No newline at end of file +add_translation("en", $english); diff --git a/mod/tinymce/start.php b/mod/tinymce/start.php index 48625f456..6aba837e0 100644 --- a/mod/tinymce/start.php +++ b/mod/tinymce/start.php @@ -33,3 +33,15 @@ function tinymce_longtext_menu($hook, $type, $items, $vars) { return $items; } + +function tinymce_get_site_language() { + + if ($site_language = elgg_get_config('language')) { + $path = elgg_get_plugins_path() . "tinymce/vendor/tinymce/jscripts/tiny_mce/langs"; + if (file_exists("$path/$site_language.js")) { + return $site_language; + } + } + + return 'en'; +} diff --git a/mod/tinymce/views/default/js/tinymce.php b/mod/tinymce/views/default/js/tinymce.php index e6e2865a5..51e99c223 100644 --- a/mod/tinymce/views/default/js/tinymce.php +++ b/mod/tinymce/views/default/js/tinymce.php @@ -38,6 +38,7 @@ elgg.tinymce.init = function() { mode : "specific_textareas", editor_selector : "elgg-input-longtext", theme : "advanced", + language : "<?php echo tinymce_get_site_language(); ?>", plugins : "lists,spellchecker,autosave,fullscreen,paste", relative_urls : false, remove_script_host : false, @@ -86,4 +87,4 @@ elgg.tinymce.init = function() { } } -elgg.register_hook_handler('init', 'system', elgg.tinymce.init);
\ No newline at end of file +elgg.register_hook_handler('init', 'system', elgg.tinymce.init); 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/vendors/jquery/i18n/jquery-ui-i18n.js b/vendors/jquery/i18n/jquery-ui-i18n.js new file mode 100644 index 000000000..366446d9e --- /dev/null +++ b/vendors/jquery/i18n/jquery-ui-i18n.js @@ -0,0 +1,1646 @@ +/*! jQuery UI - v1.8.22 - 2012-07-24 +* https://github.com/jquery/jquery-ui +* Includes: jquery.ui.datepicker-af.js, jquery.ui.datepicker-ar-DZ.js, jquery.ui.datepicker-ar.js, jquery.ui.datepicker-az.js, jquery.ui.datepicker-bg.js, jquery.ui.datepicker-bs.js, jquery.ui.datepicker-ca.js, jquery.ui.datepicker-cs.js, jquery.ui.datepicker-cy-GB.js, jquery.ui.datepicker-da.js, jquery.ui.datepicker-de.js, jquery.ui.datepicker-el.js, jquery.ui.datepicker-en-AU.js, jquery.ui.datepicker-en-GB.js, jquery.ui.datepicker-en-NZ.js, jquery.ui.datepicker-eo.js, jquery.ui.datepicker-es.js, jquery.ui.datepicker-et.js, jquery.ui.datepicker-eu.js, jquery.ui.datepicker-fa.js, jquery.ui.datepicker-fi.js, jquery.ui.datepicker-fo.js, jquery.ui.datepicker-fr-CH.js, jquery.ui.datepicker-fr.js, jquery.ui.datepicker-gl.js, jquery.ui.datepicker-he.js, jquery.ui.datepicker-hi.js, jquery.ui.datepicker-hr.js, jquery.ui.datepicker-hu.js, jquery.ui.datepicker-hy.js, jquery.ui.datepicker-id.js, jquery.ui.datepicker-is.js, jquery.ui.datepicker-it.js, jquery.ui.datepicker-ja.js, jquery.ui.datepicker-ka.js, jquery.ui.datepicker-kk.js, jquery.ui.datepicker-km.js, jquery.ui.datepicker-ko.js, jquery.ui.datepicker-lb.js, jquery.ui.datepicker-lt.js, jquery.ui.datepicker-lv.js, jquery.ui.datepicker-mk.js, jquery.ui.datepicker-ml.js, jquery.ui.datepicker-ms.js, jquery.ui.datepicker-nl-BE.js, jquery.ui.datepicker-nl.js, jquery.ui.datepicker-no.js, jquery.ui.datepicker-pl.js, jquery.ui.datepicker-pt-BR.js, jquery.ui.datepicker-pt.js, jquery.ui.datepicker-rm.js, jquery.ui.datepicker-ro.js, jquery.ui.datepicker-ru.js, jquery.ui.datepicker-sk.js, jquery.ui.datepicker-sl.js, jquery.ui.datepicker-sq.js, jquery.ui.datepicker-sr-SR.js, jquery.ui.datepicker-sr.js, jquery.ui.datepicker-sv.js, jquery.ui.datepicker-ta.js, jquery.ui.datepicker-th.js, jquery.ui.datepicker-tj.js, jquery.ui.datepicker-tr.js, jquery.ui.datepicker-uk.js, jquery.ui.datepicker-vi.js, jquery.ui.datepicker-zh-CN.js, jquery.ui.datepicker-zh-HK.js, jquery.ui.datepicker-zh-TW.js +* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ + +/* Afrikaans initialisation for the jQuery UI date picker plugin. */ +/* Written by Renier Pretorius. */ +jQuery(function($){ + $.datepicker.regional['af'] = { + closeText: 'Selekteer', + prevText: 'Vorige', + nextText: 'Volgende', + currentText: 'Vandag', + monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie', + 'Julie','Augustus','September','Oktober','November','Desember'], + monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'], + dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'], + dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'], + dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['af']); +}); + +/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ +/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ + +jQuery(function($){ + $.datepicker.regional['ar-DZ'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان', + 'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar-DZ']); +}); + +/* Arabic Translation for jQuery UI date picker plugin. */ +/* Khaled Alhourani -- me@khaledalhourani.com */ +/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ +jQuery(function($){ + $.datepicker.regional['ar'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', + 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar']); +}); +/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Jamil Najafov (necefov33@gmail.com). */ +jQuery(function($) { + $.datepicker.regional['az'] = { + closeText: 'Bağla', + prevText: '<Geri', + nextText: 'İrəli>', + currentText: 'Bugün', + monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun', + 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'], + monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun', + 'İyul','Avq','Sen','Okt','Noy','Dek'], + dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'], + dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'], + dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['az']); +}); +/* Bulgarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Stoyan Kyosev (http://svest.org). */ +jQuery(function($){ + $.datepicker.regional['bg'] = { + closeText: 'затвори', + prevText: '<назад', + nextText: 'напред>', + nextBigText: '>>', + currentText: 'днес', + monthNames: ['Януари','Февруари','Март','Април','Май','Юни', + 'Юли','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни', + 'Юли','Авг','Сеп','Окт','Нов','Дек'], + dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'], + dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bg']); +}); + +/* Bosnian i18n for the jQuery UI date picker plugin. */ +/* Written by Kenan Konjo. */ +jQuery(function($){ + $.datepicker.regional['bs'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Juni', + 'Juli','August','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bs']); +}); +/* Inicialització en català per a l'extenció 'calendar' per jQuery. */ +/* Writers: (joan.leon@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ca'] = { + closeText: 'Tancar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Avui', + monthNames: ['Gener','Febrer','Març','Abril','Maig','Juny', + 'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'], + monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Oct','Nov','Des'], + dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'], + dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'], + dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ca']); +}); +/* Czech initialisation for the jQuery UI date picker plugin. */ +/* Written by Tomas Muller (tomas@tomas-muller.net). */ +jQuery(function($){ + $.datepicker.regional['cs'] = { + closeText: 'Zavřít', + prevText: '<Dříve', + nextText: 'Později>', + currentText: 'Nyní', + monthNames: ['leden','únor','březen','duben','květen','červen', + 'červenec','srpen','září','říjen','listopad','prosinec'], + monthNamesShort: ['led','úno','bře','dub','kvě','čer', + 'čvc','srp','zář','říj','lis','pro'], + dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'], + dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'], + dayNamesMin: ['ne','po','út','st','čt','pá','so'], + weekHeader: 'Týd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cs']); +}); + +/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by William Griffiths. */ +jQuery(function($){ + $.datepicker.regional['cy-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', + 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], + monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', + 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], + dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], + dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], + dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], + weekHeader: 'Wy', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cy-GB']); +}); +/* Danish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jan Christensen ( deletestuff@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['da'] = { + closeText: 'Luk', + prevText: '<Forrige', + nextText: 'Næste>', + currentText: 'Idag', + monthNames: ['Januar','Februar','Marts','April','Maj','Juni', + 'Juli','August','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], + dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'], + dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], + weekHeader: 'Uge', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['da']); +}); + +/* German initialisation for the jQuery UI date picker plugin. */ +/* Written by Milian Wolff (mail@milianw.de). */ +jQuery(function($){ + $.datepicker.regional['de'] = { + closeText: 'schließen', + prevText: '<zurück', + nextText: 'Vor>', + currentText: 'heute', + monthNames: ['Januar','Februar','März','April','Mai','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dez'], + dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], + dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], + dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], + weekHeader: 'KW', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['de']); +}); + +/* Greek (el) initialisation for the jQuery UI date picker plugin. */ +/* Written by Alex Cicovic (http://www.alexcicovic.com) */ +jQuery(function($){ + $.datepicker.regional['el'] = { + closeText: 'Κλείσιμο', + prevText: 'Προηγούμενος', + nextText: 'Επόμενος', + currentText: 'Τρέχων Μήνας', + monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος', + 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'], + monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν', + 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'], + dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'], + dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'], + dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'], + weekHeader: 'Εβδ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['el']); +}); +/* English/Australia initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-AU'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-AU']); +}); + +/* English/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by Stuart. */ +jQuery(function($){ + $.datepicker.regional['en-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-GB']); +}); + +/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-NZ'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-NZ']); +}); + +/* Esperanto initialisation for the jQuery UI date picker plugin. */ +/* Written by Olivier M. (olivierweb@ifrance.com). */ +jQuery(function($){ + $.datepicker.regional['eo'] = { + closeText: 'Fermi', + prevText: '<Anta', + nextText: 'Sekv>', + currentText: 'Nuna', + monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio', + 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aŭg','Sep','Okt','Nov','Dec'], + dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'], + dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'], + weekHeader: 'Sb', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eo']); +}); + +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['es'] = { + closeText: 'Cerrar', + prevText: '<Ant', + nextText: 'Sig>', + currentText: 'Hoy', + monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', + 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], + monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', + 'Jul','Ago','Sep','Oct','Nov','Dic'], + dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['es']); +}); +/* Estonian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ +jQuery(function($){ + $.datepicker.regional['et'] = { + closeText: 'Sulge', + prevText: 'Eelnev', + nextText: 'Järgnev', + currentText: 'Täna', + monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni', + 'Juuli','August','September','Oktoober','November','Detsember'], + monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', + 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'], + dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], + dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], + dayNamesMin: ['P','E','T','K','N','R','L'], + weekHeader: 'näd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['et']); +}); +/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */ +/* Karrikas-ek itzulia (karrikas@karrikas.com) */ +jQuery(function($){ + $.datepicker.regional['eu'] = { + closeText: 'Egina', + prevText: '<Aur', + nextText: 'Hur>', + currentText: 'Gaur', + monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', + 'uztaila','abuztua','iraila','urria','azaroa','abendua'], + monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', + 'uzt.','abu.','ira.','urr.','aza.','abe.'], + dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], + dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], + dayNamesMin: ['ig','al','ar','az','og','ol','lr'], + weekHeader: 'As', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eu']); +}); +/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ +/* Javad Mowlanezhad -- jmowla@gmail.com */ +/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ +jQuery(function($) { + $.datepicker.regional['fa'] = { + closeText: 'بستن', + prevText: '<قبلی', + nextText: 'بعدی>', + currentText: 'امروز', + monthNames: [ + 'فروردين', + 'ارديبهشت', + 'خرداد', + 'تير', + 'مرداد', + 'شهريور', + 'مهر', + 'آبان', + 'آذر', + 'دی', + 'بهمن', + 'اسفند' + ], + monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], + dayNames: [ + 'يکشنبه', + 'دوشنبه', + 'سهشنبه', + 'چهارشنبه', + 'پنجشنبه', + 'جمعه', + 'شنبه' + ], + dayNamesShort: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + dayNamesMin: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + weekHeader: 'هف', + dateFormat: 'yy/mm/dd', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fa']); +}); +/* Finnish initialisation for the jQuery UI date picker plugin. */ +/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['fi'] = { + closeText: 'Sulje', + prevText: '«Edellinen', + nextText: 'Seuraava»', + currentText: 'Tänään', + monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', + 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], + monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', + 'Heinä','Elo','Syys','Loka','Marras','Joulu'], + dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], + dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], + dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], + weekHeader: 'Vk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fi']); +}); + +/* Faroese initialisation for the jQuery UI date picker plugin */ +/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ +jQuery(function($){ + $.datepicker.regional['fo'] = { + closeText: 'Lat aftur', + prevText: '<Fyrra', + nextText: 'Næsta>', + currentText: 'Í dag', + monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni', + 'Juli','August','September','Oktober','November','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Aug','Sep','Okt','Nov','Des'], + dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'], + dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'], + dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'], + weekHeader: 'Vk', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fo']); +}); + +/* Swiss-French initialisation for the jQuery UI date picker plugin. */ +/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ +jQuery(function($){ + $.datepicker.regional['fr-CH'] = { + closeText: 'Fermer', + prevText: '<Préc', + nextText: 'Suiv>', + currentText: 'Courant', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', + 'Jul','Aoû','Sep','Oct','Nov','Déc'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], + dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr-CH']); +}); +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault <stephane.raimbault@gmail.com> */ +jQuery(function($){ + $.datepicker.regional['fr'] = { + closeText: 'Fermer', + prevText: 'Précédent', + nextText: 'Suivant', + currentText: 'Aujourd\'hui', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin', + 'Juil.','Août','Sept.','Oct.','Nov.','Déc.'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], + dayNamesMin: ['D','L','M','M','J','V','S'], + weekHeader: 'Sem.', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr']); +}); + +/* Galician localization for 'UI date picker' jQuery extension. */ +/* Translated by Jorge Barreiro <yortx.barry@gmail.com>. */ +jQuery(function($){ + $.datepicker.regional['gl'] = { + closeText: 'Pechar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Hoxe', + monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', + 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], + monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', + 'Xul','Ago','Set','Out','Nov','Dec'], + dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['gl']); +}); +/* Hebrew initialisation for the UI Datepicker extension. */ +/* Written by Amir Hardon (ahardon at gmail dot com). */ +jQuery(function($){ + $.datepicker.regional['he'] = { + closeText: 'סגור', + prevText: '<הקודם', + nextText: 'הבא>', + currentText: 'היום', + monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', + 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], + monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', + 'יולי','אוג','ספט','אוק','נוב','דצמ'], + dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], + dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['he']); +}); + +/* Hindi initialisation for the jQuery UI date picker plugin. */ +/* Written by Michael Dawart. */ +jQuery(function($){ + $.datepicker.regional['hi'] = { + closeText: 'बंद', + prevText: 'पिछला', + nextText: 'अगला', + currentText: 'आज', + monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', + 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], + monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', + 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], + dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], + dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + weekHeader: 'हफ्ता', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hi']); +}); + +/* Croatian i18n for the jQuery UI date picker plugin. */ +/* Written by Vjekoslav Nesek. */ +jQuery(function($){ + $.datepicker.regional['hr'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj', + 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'], + monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip', + 'Srp','Kol','Ruj','Lis','Stu','Pro'], + dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Tje', + dateFormat: 'dd.mm.yy.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hr']); +}); +/* Hungarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */ +jQuery(function($){ + $.datepicker.regional['hu'] = { + closeText: 'bezár', + prevText: 'vissza', + nextText: 'előre', + currentText: 'ma', + monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', + 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], + monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', + 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'], + dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], + dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'], + dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], + weekHeader: 'Hét', + dateFormat: 'yy.mm.dd.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hu']); +}); + +/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ +jQuery(function($){ + $.datepicker.regional['hy'] = { + closeText: 'Փակել', + prevText: '<Նախ.', + nextText: 'Հաջ.>', + currentText: 'Այսօր', + monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս', + 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'], + monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս', + 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'], + dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'], + dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + weekHeader: 'ՇԲՏ', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hy']); +}); +/* Indonesian initialisation for the jQuery UI date picker plugin. */ +/* Written by Deden Fathurahman (dedenf@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['id'] = { + closeText: 'Tutup', + prevText: '<mundur', + nextText: 'maju>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Maret','April','Mei','Juni', + 'Juli','Agustus','September','Oktober','Nopember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Agus','Sep','Okt','Nop','Des'], + dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'], + dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'], + dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['id']); +}); +/* Icelandic initialisation for the jQuery UI date picker plugin. */ +/* Written by Haukur H. Thorsson (haukur@eskill.is). */ +jQuery(function($){ + $.datepicker.regional['is'] = { + closeText: 'Loka', + prevText: '< Fyrri', + nextText: 'Næsti >', + currentText: 'Í dag', + monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní', + 'Júlí','Ágúst','September','Október','Nóvember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún', + 'Júl','Ágú','Sep','Okt','Nóv','Des'], + dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'], + dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'], + dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'], + weekHeader: 'Vika', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['is']); +}); +/* Italian initialisation for the jQuery UI date picker plugin. */ +/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['it'] = { + closeText: 'Chiudi', + prevText: '<Prec', + nextText: 'Succ>', + currentText: 'Oggi', + monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', + 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], + monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', + 'Lug','Ago','Set','Ott','Nov','Dic'], + dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], + dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], + dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['it']); +}); + +/* Japanese initialisation for the jQuery UI date picker plugin. */ +/* Written by Kentaro SATO (kentaro@ranvis.com). */ +jQuery(function($){ + $.datepicker.regional['ja'] = { + closeText: '閉じる', + prevText: '<前', + nextText: '次>', + currentText: '今日', + monthNames: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + monthNamesShort: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'], + dayNamesShort: ['日','月','火','水','木','金','土'], + dayNamesMin: ['日','月','火','水','木','金','土'], + weekHeader: '週', + dateFormat: 'yy/mm/dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['ja']); +}); +/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ka'] = { + closeText: 'დახურვა', + prevText: '< წინა', + nextText: 'შემდეგი >', + currentText: 'დღეს', + monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], + monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], + dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], + dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + weekHeader: 'კვირა', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ka']); +}); + +/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['kk'] = { + closeText: 'Жабу', + prevText: '<Алдыңғы', + nextText: 'Келесі>', + currentText: 'Бүгін', + monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', + 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], + monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', + 'Шіл','Там','Қыр','Қаз','Қар','Жел'], + dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], + dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], + dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], + weekHeader: 'Не', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['kk']); +}); + +/* Khmer initialisation for the jQuery calendar extension. */ +/* Written by Chandara Om (chandara.teacher@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['km'] = { + closeText: 'ធ្វើរួច', + prevText: 'មុន', + nextText: 'បន្ទាប់', + currentText: 'ថ្ងៃនេះ', + monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], + dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + weekHeader: 'សប្ដាហ៍', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['km']); +}); + +/* Korean initialisation for the jQuery calendar extension. */ +/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ +jQuery(function($){ + $.datepicker.regional['ko'] = { + closeText: '닫기', + prevText: '이전달', + nextText: '다음달', + currentText: '오늘', + monthNames: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + monthNamesShort: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], + dayNamesShort: ['일','월','화','수','목','금','토'], + dayNamesMin: ['일','월','화','수','목','금','토'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '년'}; + $.datepicker.setDefaults($.datepicker.regional['ko']); +}); +/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ +/* Written by Michel Weimerskirch <michel@weimerskirch.net> */ +jQuery(function($){ + $.datepicker.regional['lb'] = { + closeText: 'Fäerdeg', + prevText: 'Zréck', + nextText: 'Weider', + currentText: 'Haut', + monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], + dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], + dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], + weekHeader: 'W', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lb']); +}); + +/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas <arturas@avalon.lt> */ +jQuery(function($){ + $.datepicker.regional['lt'] = { + closeText: 'Uždaryti', + prevText: '<Atgal', + nextText: 'Pirmyn>', + currentText: 'Šiandien', + monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis', + 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'], + monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir', + 'Lie','Rugp','Rugs','Spa','Lap','Gru'], + dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'], + dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'], + dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lt']); +}); +/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas <arturas.paleicikas@metasite.net> */ +jQuery(function($){ + $.datepicker.regional['lv'] = { + closeText: 'Aizvērt', + prevText: 'Iepr', + nextText: 'Nāka', + currentText: 'Šodien', + monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', + 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn', + 'Jūl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], + dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], + dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], + weekHeader: 'Nav', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lv']); +}); +/* Macedonian i18n for the jQuery UI date picker plugin. */ +/* Written by Stojce Slavkovski. */ +jQuery(function($){ + $.datepicker.regional['mk'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Денес', + monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', + 'Јули','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Ное','Дек'], + dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], + dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], + weekHeader: 'Сед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['mk']); +}); + +/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Saji Nediyanchath (saji89@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ml'] = { + closeText: 'ശരി', + prevText: 'മുന്നത്തെ', + nextText: 'അടുത്തത് ', + currentText: 'ഇന്ന്', + monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്ച്ച്','ഏപ്രില്','മേയ്','ജൂണ്', + 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്','ഒക്ടോബര്','നവംബര്','ഡിസംബര്'], + monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്', 'ഏപ്രി', 'മേയ്', 'ജൂണ്', + 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'], + dayNames: ['ഞായര്', 'തിങ്കള്', 'ചൊവ്വ', 'ബുധന്', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'], + weekHeader: 'ആ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ml']); +}); + +/* Malaysian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ +jQuery(function($){ + $.datepicker.regional['ms'] = { + closeText: 'Tutup', + prevText: '<Sebelum', + nextText: 'Selepas>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Mac','April','Mei','Jun', + 'Julai','Ogos','September','Oktober','November','Disember'], + monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun', + 'Jul','Ogo','Sep','Okt','Nov','Dis'], + dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'], + dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'], + dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ms']); +}); +/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ +/* David De Sloovere @DavidDeSloovere */ +jQuery(function($){ + $.datepicker.regional['nl-BE'] = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['nl-BE']); +}); + +/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Mathias Bynens <http://mathiasbynens.be/> */ +jQuery(function($){ + $.datepicker.regional.nl = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional.nl); +}); +/* Norwegian initialisation for the jQuery UI date picker plugin. */ +/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ + +jQuery(function($){ + $.datepicker.regional['no'] = { + closeText: 'Lukk', + prevText: '«Forrige', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], + weekHeader: 'Uke', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + }; + $.datepicker.setDefaults($.datepicker.regional['no']); +}); + +/* Polish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pl'] = { + closeText: 'Zamknij', + prevText: '<Poprzedni', + nextText: 'Następny>', + currentText: 'Dziś', + monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', + 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], + monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze', + 'Lip','Sie','Wrz','Pa','Lis','Gru'], + dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'], + dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], + dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], + weekHeader: 'Tydz', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pl']); +}); + +/* Brazilian initialisation for the jQuery UI date picker plugin. */ +/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pt-BR'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Próximo>', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt-BR']); +}); +/* Portuguese initialisation for the jQuery UI date picker plugin. */ +jQuery(function($){ + $.datepicker.regional['pt'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Seguinte', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sem', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt']); +}); +/* Romansh initialisation for the jQuery UI date picker plugin. */ +/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ +jQuery(function($){ + $.datepicker.regional['rm'] = { + closeText: 'Serrar', + prevText: '<Suandant', + nextText: 'Precedent>', + currentText: 'Actual', + monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], + monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], + dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], + dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], + dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], + weekHeader: 'emna', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['rm']); +}); + +/* Romanian initialisation for the jQuery UI date picker plugin. + * + * Written by Edmond L. (ll_edmond@walla.com) + * and Ionut G. Stan (ionut.g.stan@gmail.com) + */ +jQuery(function($){ + $.datepicker.regional['ro'] = { + closeText: 'Închide', + prevText: '« Luna precedentă', + nextText: 'Luna următoare »', + currentText: 'Azi', + monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie', + 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'], + monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', + 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], + dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'], + dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'], + weekHeader: 'Săpt', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ro']); +}); + +/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Andrew Stromnov (stromnov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ru'] = { + closeText: 'Закрыть', + prevText: '<Пред', + nextText: 'След>', + currentText: 'Сегодня', + monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', + 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], + dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], + dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Нед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ru']); +}); +/* Slovak initialisation for the jQuery UI date picker plugin. */ +/* Written by Vojtech Rinik (vojto@hmm.sk). */ +jQuery(function($){ + $.datepicker.regional['sk'] = { + closeText: 'Zavrieť', + prevText: '<Predchádzajúci', + nextText: 'Nasledujúci>', + currentText: 'Dnes', + monthNames: ['Január','Február','Marec','Apríl','Máj','Jún', + 'Júl','August','September','Október','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', + 'Júl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'], + dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], + dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], + weekHeader: 'Ty', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sk']); +}); + +/* Slovenian initialisation for the jQuery UI date picker plugin. */ +/* Written by Jaka Jancar (jaka@kubje.org). */ +/* c = č, s = š z = ž C = Č S = Š Z = Ž */ +jQuery(function($){ + $.datepicker.regional['sl'] = { + closeText: 'Zapri', + prevText: '<Prejšnji', + nextText: 'Naslednji>', + currentText: 'Trenutni', + monthNames: ['Januar','Februar','Marec','April','Maj','Junij', + 'Julij','Avgust','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'], + dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'], + dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'], + weekHeader: 'Teden', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sl']); +}); + +/* Albanian initialisation for the jQuery UI date picker plugin. */ +/* Written by Flakron Bytyqi (flakron@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['sq'] = { + closeText: 'mbylle', + prevText: '<mbrapa', + nextText: 'Përpara>', + currentText: 'sot', + monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor', + 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'], + monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer', + 'Kor','Gus','Sht','Tet','Nën','Dhj'], + dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'], + dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'], + dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'], + weekHeader: 'Ja', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sq']); +}); + +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr-SR'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Jun', + 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Sed', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr-SR']); +}); + +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Данас', + monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун', + 'Јул','Август','Септембар','Октобар','Новембар','Децембар'], + monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Нов','Дец'], + dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'], + dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'], + dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'], + weekHeader: 'Сед', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr']); +}); + +/* Swedish initialisation for the jQuery UI date picker plugin. */ +/* Written by Anders Ekdahl ( anders@nomadiz.se). */ +jQuery(function($){ + $.datepicker.regional['sv'] = { + closeText: 'Stäng', + prevText: '«Förra', + nextText: 'Nästa»', + currentText: 'Idag', + monthNames: ['Januari','Februari','Mars','April','Maj','Juni', + 'Juli','Augusti','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'], + dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'], + dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], + weekHeader: 'Ve', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sv']); +}); + +/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by S A Sureshkumar (saskumar@live.com). */ +jQuery(function($){ + $.datepicker.regional['ta'] = { + closeText: 'மூடு', + prevText: 'முன்னையது', + nextText: 'அடுத்தது', + currentText: 'இன்று', + monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி', + 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'], + monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி', + 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'], + dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'], + dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'], + dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'], + weekHeader: 'Не', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ta']); +}); + +/* Thai initialisation for the jQuery UI date picker plugin. */ +/* Written by pipo (pipo@sixhead.com). */ +jQuery(function($){ + $.datepicker.regional['th'] = { + closeText: 'ปิด', + prevText: '« ย้อน', + nextText: 'ถัดไป »', + currentText: 'วันนี้', + monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', + 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], + monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', + 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], + dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], + dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['th']); +}); +/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['tj'] = { + closeText: 'Идома', + prevText: '<Қафо', + nextText: 'Пеш>', + currentText: 'Имрӯз', + monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн', + 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'], + dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'], + dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'], + weekHeader: 'Хф', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tj']); +}); +/* Turkish initialisation for the jQuery UI date picker plugin. */ +/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ +jQuery(function($){ + $.datepicker.regional['tr'] = { + closeText: 'kapat', + prevText: '<geri', + nextText: 'ileri>', + currentText: 'bugün', + monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', + 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'], + monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz', + 'Tem','Ağu','Eyl','Eki','Kas','Ara'], + dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'], + dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tr']); +}); +/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ +/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['uk'] = { + closeText: 'Закрити', + prevText: '<', + nextText: '>', + currentText: 'Сьогодні', + monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень', + 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'], + monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер', + 'Лип','Сер','Вер','Жов','Лис','Гру'], + dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'], + dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'], + dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Тиж', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['uk']); +}); +/* Vietnamese initialisation for the jQuery UI date picker plugin. */ +/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ +jQuery(function($){ + $.datepicker.regional['vi'] = { + closeText: 'Đóng', + prevText: '<Trước', + nextText: 'Tiếp>', + currentText: 'Hôm nay', + monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', + 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'], + monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', + 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'], + dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'], + dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + weekHeader: 'Tu', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['vi']); +}); + +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Cloudream (cloudream@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-CN'] = { + closeText: '关闭', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一','二','三','四','五','六', + '七','八','九','十','十一','十二'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-CN']); +}); + +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by SCCY (samuelcychan@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-HK'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一','二','三','四','五','六', + '七','八','九','十','十一','十二'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-HK']); +}); + +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Ressol (ressol@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-TW'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一','二','三','四','五','六', + '七','八','九','十','十一','十二'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy/mm/dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-TW']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-af.js b/vendors/jquery/i18n/jquery.ui.datepicker-af.js new file mode 100644 index 000000000..0922ef7a1 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-af.js @@ -0,0 +1,23 @@ +/* Afrikaans initialisation for the jQuery UI date picker plugin. */ +/* Written by Renier Pretorius. */ +jQuery(function($){ + $.datepicker.regional['af'] = { + closeText: 'Selekteer', + prevText: 'Vorige', + nextText: 'Volgende', + currentText: 'Vandag', + monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie', + 'Julie','Augustus','September','Oktober','November','Desember'], + monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'], + dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'], + dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'], + dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['af']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ar-DZ.js b/vendors/jquery/i18n/jquery.ui.datepicker-ar-DZ.js new file mode 100644 index 000000000..e0e1685d8 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ar-DZ.js @@ -0,0 +1,23 @@ +/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ +/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ + +jQuery(function($){ + $.datepicker.regional['ar-DZ'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان', + 'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar-DZ']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ar.js b/vendors/jquery/i18n/jquery.ui.datepicker-ar.js new file mode 100644 index 000000000..8a9218d8b --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ar.js @@ -0,0 +1,23 @@ +/* Arabic Translation for jQuery UI date picker plugin. */ +/* Khaled Alhourani -- me@khaledalhourani.com */ +/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ +jQuery(function($){ + $.datepicker.regional['ar'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', + 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-az.js b/vendors/jquery/i18n/jquery.ui.datepicker-az.js new file mode 100644 index 000000000..57802a40b --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-az.js @@ -0,0 +1,23 @@ +/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Jamil Najafov (necefov33@gmail.com). */ +jQuery(function($) { + $.datepicker.regional['az'] = { + closeText: 'Bağla', + prevText: '<Geri', + nextText: 'İrəli>', + currentText: 'Bugün', + monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun', + 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'], + monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun', + 'İyul','Avq','Sen','Okt','Noy','Dek'], + dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'], + dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'], + dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['az']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-bg.js b/vendors/jquery/i18n/jquery.ui.datepicker-bg.js new file mode 100644 index 000000000..c19d20fb1 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-bg.js @@ -0,0 +1,24 @@ +/* Bulgarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Stoyan Kyosev (http://svest.org). */ +jQuery(function($){ + $.datepicker.regional['bg'] = { + closeText: 'затвори', + prevText: '<назад', + nextText: 'напред>', + nextBigText: '>>', + currentText: 'днес', + monthNames: ['Януари','Февруари','Март','Април','Май','Юни', + 'Юли','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни', + 'Юли','Авг','Сеп','Окт','Нов','Дек'], + dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'], + dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bg']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-bs.js b/vendors/jquery/i18n/jquery.ui.datepicker-bs.js new file mode 100644 index 000000000..d4dc8b0ec --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-bs.js @@ -0,0 +1,23 @@ +/* Bosnian i18n for the jQuery UI date picker plugin. */ +/* Written by Kenan Konjo. */ +jQuery(function($){ + $.datepicker.regional['bs'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Juni', + 'Juli','August','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bs']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ca.js b/vendors/jquery/i18n/jquery.ui.datepicker-ca.js new file mode 100644 index 000000000..b128e699e --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ca.js @@ -0,0 +1,23 @@ +/* Inicialització en català per a l'extenció 'calendar' per jQuery. */ +/* Writers: (joan.leon@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ca'] = { + closeText: 'Tancar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Avui', + monthNames: ['Gener','Febrer','Març','Abril','Maig','Juny', + 'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'], + monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Oct','Nov','Des'], + dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'], + dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'], + dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ca']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-cs.js b/vendors/jquery/i18n/jquery.ui.datepicker-cs.js new file mode 100644 index 000000000..9805bcdb8 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-cs.js @@ -0,0 +1,23 @@ +/* Czech initialisation for the jQuery UI date picker plugin. */ +/* Written by Tomas Muller (tomas@tomas-muller.net). */ +jQuery(function($){ + $.datepicker.regional['cs'] = { + closeText: 'Zavřít', + prevText: '<Dříve', + nextText: 'Později>', + currentText: 'Nyní', + monthNames: ['leden','únor','březen','duben','květen','červen', + 'červenec','srpen','září','říjen','listopad','prosinec'], + monthNamesShort: ['led','úno','bře','dub','kvě','čer', + 'čvc','srp','zář','říj','lis','pro'], + dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'], + dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'], + dayNamesMin: ['ne','po','út','st','čt','pá','so'], + weekHeader: 'Týd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cs']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-cy-GB.js b/vendors/jquery/i18n/jquery.ui.datepicker-cy-GB.js new file mode 100644 index 000000000..dfee2f9d4 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-cy-GB.js @@ -0,0 +1,23 @@ +/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by William Griffiths. */ +jQuery(function($){ + $.datepicker.regional['cy-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', + 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], + monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', + 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], + dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], + dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], + dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], + weekHeader: 'Wy', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cy-GB']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-da.js b/vendors/jquery/i18n/jquery.ui.datepicker-da.js new file mode 100644 index 000000000..176044e18 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-da.js @@ -0,0 +1,23 @@ +/* Danish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jan Christensen ( deletestuff@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['da'] = { + closeText: 'Luk', + prevText: '<Forrige', + nextText: 'Næste>', + currentText: 'Idag', + monthNames: ['Januar','Februar','Marts','April','Maj','Juni', + 'Juli','August','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], + dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'], + dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], + weekHeader: 'Uge', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['da']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-de.js b/vendors/jquery/i18n/jquery.ui.datepicker-de.js new file mode 100644 index 000000000..f3ef9e82c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-de.js @@ -0,0 +1,23 @@ +/* German initialisation for the jQuery UI date picker plugin. */ +/* Written by Milian Wolff (mail@milianw.de). */ +jQuery(function($){ + $.datepicker.regional['de'] = { + closeText: 'schließen', + prevText: '<zurück', + nextText: 'Vor>', + currentText: 'heute', + monthNames: ['Januar','Februar','März','April','Mai','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dez'], + dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], + dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], + dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], + weekHeader: 'KW', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['de']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-el.js b/vendors/jquery/i18n/jquery.ui.datepicker-el.js new file mode 100644 index 000000000..6d775f995 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-el.js @@ -0,0 +1,23 @@ +/* Greek (el) initialisation for the jQuery UI date picker plugin. */ +/* Written by Alex Cicovic (http://www.alexcicovic.com) */ +jQuery(function($){ + $.datepicker.regional['el'] = { + closeText: 'Κλείσιμο', + prevText: 'Προηγούμενος', + nextText: 'Επόμενος', + currentText: 'Τρέχων Μήνας', + monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος', + 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'], + monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν', + 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'], + dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'], + dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'], + dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'], + weekHeader: 'Εβδ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['el']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-en-AU.js b/vendors/jquery/i18n/jquery.ui.datepicker-en-AU.js new file mode 100644 index 000000000..c1a1020a1 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-en-AU.js @@ -0,0 +1,23 @@ +/* English/Australia initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-AU'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-AU']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-en-GB.js b/vendors/jquery/i18n/jquery.ui.datepicker-en-GB.js new file mode 100644 index 000000000..16a096e75 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-en-GB.js @@ -0,0 +1,23 @@ +/* English/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by Stuart. */ +jQuery(function($){ + $.datepicker.regional['en-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-GB']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-en-NZ.js b/vendors/jquery/i18n/jquery.ui.datepicker-en-NZ.js new file mode 100644 index 000000000..7819df052 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-en-NZ.js @@ -0,0 +1,23 @@ +/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-NZ'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-NZ']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-eo.js b/vendors/jquery/i18n/jquery.ui.datepicker-eo.js new file mode 100644 index 000000000..6cabc2c46 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-eo.js @@ -0,0 +1,23 @@ +/* Esperanto initialisation for the jQuery UI date picker plugin. */ +/* Written by Olivier M. (olivierweb@ifrance.com). */ +jQuery(function($){ + $.datepicker.regional['eo'] = { + closeText: 'Fermi', + prevText: '<Anta', + nextText: 'Sekv>', + currentText: 'Nuna', + monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio', + 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aŭg','Sep','Okt','Nov','Dec'], + dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'], + dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'], + weekHeader: 'Sb', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eo']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-es.js b/vendors/jquery/i18n/jquery.ui.datepicker-es.js new file mode 100644 index 000000000..a02133de3 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-es.js @@ -0,0 +1,23 @@ +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['es'] = { + closeText: 'Cerrar', + prevText: '<Ant', + nextText: 'Sig>', + currentText: 'Hoy', + monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', + 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], + monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', + 'Jul','Ago','Sep','Oct','Nov','Dic'], + dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['es']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-et.js b/vendors/jquery/i18n/jquery.ui.datepicker-et.js new file mode 100644 index 000000000..32702b243 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-et.js @@ -0,0 +1,23 @@ +/* Estonian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ +jQuery(function($){ + $.datepicker.regional['et'] = { + closeText: 'Sulge', + prevText: 'Eelnev', + nextText: 'Järgnev', + currentText: 'Täna', + monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni', + 'Juuli','August','September','Oktoober','November','Detsember'], + monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', + 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'], + dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], + dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], + dayNamesMin: ['P','E','T','K','N','R','L'], + weekHeader: 'näd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['et']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-eu.js b/vendors/jquery/i18n/jquery.ui.datepicker-eu.js new file mode 100644 index 000000000..ff66e494c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-eu.js @@ -0,0 +1,23 @@ +/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */ +/* Karrikas-ek itzulia (karrikas@karrikas.com) */ +jQuery(function($){ + $.datepicker.regional['eu'] = { + closeText: 'Egina', + prevText: '<Aur', + nextText: 'Hur>', + currentText: 'Gaur', + monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', + 'uztaila','abuztua','iraila','urria','azaroa','abendua'], + monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', + 'uzt.','abu.','ira.','urr.','aza.','abe.'], + dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], + dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], + dayNamesMin: ['ig','al','ar','az','og','ol','lr'], + weekHeader: 'As', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eu']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-fa.js b/vendors/jquery/i18n/jquery.ui.datepicker-fa.js new file mode 100644 index 000000000..be8acd2a5 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-fa.js @@ -0,0 +1,59 @@ +/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ +/* Javad Mowlanezhad -- jmowla@gmail.com */ +/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ +jQuery(function($) { + $.datepicker.regional['fa'] = { + closeText: 'بستن', + prevText: '<قبلی', + nextText: 'بعدی>', + currentText: 'امروز', + monthNames: [ + 'فروردين', + 'ارديبهشت', + 'خرداد', + 'تير', + 'مرداد', + 'شهريور', + 'مهر', + 'آبان', + 'آذر', + 'دی', + 'بهمن', + 'اسفند' + ], + monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], + dayNames: [ + 'يکشنبه', + 'دوشنبه', + 'سهشنبه', + 'چهارشنبه', + 'پنجشنبه', + 'جمعه', + 'شنبه' + ], + dayNamesShort: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + dayNamesMin: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + weekHeader: 'هف', + dateFormat: 'yy/mm/dd', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fa']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-fi.js b/vendors/jquery/i18n/jquery.ui.datepicker-fi.js new file mode 100644 index 000000000..4c5adda35 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-fi.js @@ -0,0 +1,23 @@ +/* Finnish initialisation for the jQuery UI date picker plugin. */ +/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['fi'] = { + closeText: 'Sulje', + prevText: '«Edellinen', + nextText: 'Seuraava»', + currentText: 'Tänään', + monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', + 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], + monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', + 'Heinä','Elo','Syys','Loka','Marras','Joulu'], + dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], + dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], + dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], + weekHeader: 'Vk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fi']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-fo.js b/vendors/jquery/i18n/jquery.ui.datepicker-fo.js new file mode 100644 index 000000000..8a6cb99cb --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-fo.js @@ -0,0 +1,23 @@ +/* Faroese initialisation for the jQuery UI date picker plugin */ +/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ +jQuery(function($){ + $.datepicker.regional['fo'] = { + closeText: 'Lat aftur', + prevText: '<Fyrra', + nextText: 'Næsta>', + currentText: 'Í dag', + monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni', + 'Juli','August','September','Oktober','November','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Aug','Sep','Okt','Nov','Des'], + dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'], + dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'], + dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'], + weekHeader: 'Vk', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fo']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-fr-CH.js b/vendors/jquery/i18n/jquery.ui.datepicker-fr-CH.js new file mode 100644 index 000000000..244eacff4 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-fr-CH.js @@ -0,0 +1,23 @@ +/* Swiss-French initialisation for the jQuery UI date picker plugin. */ +/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ +jQuery(function($){ + $.datepicker.regional['fr-CH'] = { + closeText: 'Fermer', + prevText: '<Préc', + nextText: 'Suiv>', + currentText: 'Courant', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', + 'Jul','Aoû','Sep','Oct','Nov','Déc'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], + dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr-CH']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-fr.js b/vendors/jquery/i18n/jquery.ui.datepicker-fr.js new file mode 100644 index 000000000..7e793639f --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-fr.js @@ -0,0 +1,25 @@ +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault <stephane.raimbault@gmail.com> */ +jQuery(function($){ + $.datepicker.regional['fr'] = { + closeText: 'Fermer', + prevText: 'Précédent', + nextText: 'Suivant', + currentText: 'Aujourd\'hui', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin', + 'Juil.','Août','Sept.','Oct.','Nov.','Déc.'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], + dayNamesMin: ['D','L','M','M','J','V','S'], + weekHeader: 'Sem.', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-gl.js b/vendors/jquery/i18n/jquery.ui.datepicker-gl.js new file mode 100644 index 000000000..278403e8f --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-gl.js @@ -0,0 +1,23 @@ +/* Galician localization for 'UI date picker' jQuery extension. */ +/* Translated by Jorge Barreiro <yortx.barry@gmail.com>. */ +jQuery(function($){ + $.datepicker.regional['gl'] = { + closeText: 'Pechar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Hoxe', + monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', + 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], + monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', + 'Xul','Ago','Set','Out','Nov','Dec'], + dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['gl']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-he.js b/vendors/jquery/i18n/jquery.ui.datepicker-he.js new file mode 100644 index 000000000..135cdec1d --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-he.js @@ -0,0 +1,23 @@ +/* Hebrew initialisation for the UI Datepicker extension. */ +/* Written by Amir Hardon (ahardon at gmail dot com). */ +jQuery(function($){ + $.datepicker.regional['he'] = { + closeText: 'סגור', + prevText: '<הקודם', + nextText: 'הבא>', + currentText: 'היום', + monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', + 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], + monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', + 'יולי','אוג','ספט','אוק','נוב','דצמ'], + dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], + dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['he']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-hi.js b/vendors/jquery/i18n/jquery.ui.datepicker-hi.js new file mode 100644 index 000000000..6c563b997 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-hi.js @@ -0,0 +1,23 @@ +/* Hindi initialisation for the jQuery UI date picker plugin. */ +/* Written by Michael Dawart. */ +jQuery(function($){ + $.datepicker.regional['hi'] = { + closeText: 'बंद', + prevText: 'पिछला', + nextText: 'अगला', + currentText: 'आज', + monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', + 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], + monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', + 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], + dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], + dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + weekHeader: 'हफ्ता', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hi']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-hr.js b/vendors/jquery/i18n/jquery.ui.datepicker-hr.js new file mode 100644 index 000000000..1eb3dd926 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-hr.js @@ -0,0 +1,23 @@ +/* Croatian i18n for the jQuery UI date picker plugin. */ +/* Written by Vjekoslav Nesek. */ +jQuery(function($){ + $.datepicker.regional['hr'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj', + 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'], + monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip', + 'Srp','Kol','Ruj','Lis','Stu','Pro'], + dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Tje', + dateFormat: 'dd.mm.yy.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hr']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-hu.js b/vendors/jquery/i18n/jquery.ui.datepicker-hu.js new file mode 100644 index 000000000..b28c268c1 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-hu.js @@ -0,0 +1,23 @@ +/* Hungarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */ +jQuery(function($){ + $.datepicker.regional['hu'] = { + closeText: 'bezár', + prevText: 'vissza', + nextText: 'előre', + currentText: 'ma', + monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', + 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], + monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', + 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'], + dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], + dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'], + dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], + weekHeader: 'Hét', + dateFormat: 'yy.mm.dd.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hu']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-hy.js b/vendors/jquery/i18n/jquery.ui.datepicker-hy.js new file mode 100644 index 000000000..c6cc1946c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-hy.js @@ -0,0 +1,23 @@ +/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ +jQuery(function($){ + $.datepicker.regional['hy'] = { + closeText: 'Փակել', + prevText: '<Նախ.', + nextText: 'Հաջ.>', + currentText: 'Այսօր', + monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս', + 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'], + monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս', + 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'], + dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'], + dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + weekHeader: 'ՇԲՏ', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hy']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-id.js b/vendors/jquery/i18n/jquery.ui.datepicker-id.js new file mode 100644 index 000000000..c626fbb7b --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-id.js @@ -0,0 +1,23 @@ +/* Indonesian initialisation for the jQuery UI date picker plugin. */ +/* Written by Deden Fathurahman (dedenf@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['id'] = { + closeText: 'Tutup', + prevText: '<mundur', + nextText: 'maju>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Maret','April','Mei','Juni', + 'Juli','Agustus','September','Oktober','Nopember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Agus','Sep','Okt','Nop','Des'], + dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'], + dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'], + dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['id']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-is.js b/vendors/jquery/i18n/jquery.ui.datepicker-is.js new file mode 100644 index 000000000..c53235a49 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-is.js @@ -0,0 +1,23 @@ +/* Icelandic initialisation for the jQuery UI date picker plugin. */ +/* Written by Haukur H. Thorsson (haukur@eskill.is). */ +jQuery(function($){ + $.datepicker.regional['is'] = { + closeText: 'Loka', + prevText: '< Fyrri', + nextText: 'Næsti >', + currentText: 'Í dag', + monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní', + 'Júlí','Ágúst','September','Október','Nóvember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún', + 'Júl','Ágú','Sep','Okt','Nóv','Des'], + dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'], + dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'], + dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'], + weekHeader: 'Vika', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['is']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-it.js b/vendors/jquery/i18n/jquery.ui.datepicker-it.js new file mode 100644 index 000000000..59da2df67 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-it.js @@ -0,0 +1,23 @@ +/* Italian initialisation for the jQuery UI date picker plugin. */ +/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['it'] = { + closeText: 'Chiudi', + prevText: '<Prec', + nextText: 'Succ>', + currentText: 'Oggi', + monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', + 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], + monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', + 'Lug','Ago','Set','Ott','Nov','Dic'], + dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], + dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], + dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['it']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ja.js b/vendors/jquery/i18n/jquery.ui.datepicker-ja.js new file mode 100644 index 000000000..7eb4268d4 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ja.js @@ -0,0 +1,23 @@ +/* Japanese initialisation for the jQuery UI date picker plugin. */ +/* Written by Kentaro SATO (kentaro@ranvis.com). */ +jQuery(function($){ + $.datepicker.regional['ja'] = { + closeText: '閉じる', + prevText: '<前', + nextText: '次>', + currentText: '今日', + monthNames: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + monthNamesShort: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'], + dayNamesShort: ['日','月','火','水','木','金','土'], + dayNamesMin: ['日','月','火','水','木','金','土'], + weekHeader: '週', + dateFormat: 'yy/mm/dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['ja']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ka.js b/vendors/jquery/i18n/jquery.ui.datepicker-ka.js new file mode 100644 index 000000000..c10658d79 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ka.js @@ -0,0 +1,21 @@ +/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ka'] = { + closeText: 'დახურვა', + prevText: '< წინა', + nextText: 'შემდეგი >', + currentText: 'დღეს', + monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], + monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], + dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], + dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + weekHeader: 'კვირა', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ka']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-kk.js b/vendors/jquery/i18n/jquery.ui.datepicker-kk.js new file mode 100644 index 000000000..79e3f2481 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-kk.js @@ -0,0 +1,23 @@ +/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['kk'] = { + closeText: 'Жабу', + prevText: '<Алдыңғы', + nextText: 'Келесі>', + currentText: 'Бүгін', + monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', + 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], + monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', + 'Шіл','Там','Қыр','Қаз','Қар','Жел'], + dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], + dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], + dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], + weekHeader: 'Не', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['kk']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-km.js b/vendors/jquery/i18n/jquery.ui.datepicker-km.js new file mode 100644 index 000000000..f9c4e3a02 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-km.js @@ -0,0 +1,23 @@ +/* Khmer initialisation for the jQuery calendar extension. */ +/* Written by Chandara Om (chandara.teacher@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['km'] = { + closeText: 'ធ្វើរួច', + prevText: 'មុន', + nextText: 'បន្ទាប់', + currentText: 'ថ្ងៃនេះ', + monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], + dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + weekHeader: 'សប្ដាហ៍', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['km']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ko.js b/vendors/jquery/i18n/jquery.ui.datepicker-ko.js new file mode 100644 index 000000000..04112424d --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ko.js @@ -0,0 +1,23 @@ +/* Korean initialisation for the jQuery calendar extension. */ +/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ +jQuery(function($){ + $.datepicker.regional['ko'] = { + closeText: '닫기', + prevText: '이전달', + nextText: '다음달', + currentText: '오늘', + monthNames: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + monthNamesShort: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], + dayNamesShort: ['일','월','화','수','목','금','토'], + dayNamesMin: ['일','월','화','수','목','금','토'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '년'}; + $.datepicker.setDefaults($.datepicker.regional['ko']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-lb.js b/vendors/jquery/i18n/jquery.ui.datepicker-lb.js new file mode 100644 index 000000000..87c79d594 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-lb.js @@ -0,0 +1,23 @@ +/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ +/* Written by Michel Weimerskirch <michel@weimerskirch.net> */ +jQuery(function($){ + $.datepicker.regional['lb'] = { + closeText: 'Fäerdeg', + prevText: 'Zréck', + nextText: 'Weider', + currentText: 'Haut', + monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], + dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], + dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], + weekHeader: 'W', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lb']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-lt.js b/vendors/jquery/i18n/jquery.ui.datepicker-lt.js new file mode 100644 index 000000000..67d5119ca --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-lt.js @@ -0,0 +1,23 @@ +/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas <arturas@avalon.lt> */ +jQuery(function($){ + $.datepicker.regional['lt'] = { + closeText: 'Uždaryti', + prevText: '<Atgal', + nextText: 'Pirmyn>', + currentText: 'Šiandien', + monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis', + 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'], + monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir', + 'Lie','Rugp','Rugs','Spa','Lap','Gru'], + dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'], + dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'], + dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lt']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-lv.js b/vendors/jquery/i18n/jquery.ui.datepicker-lv.js new file mode 100644 index 000000000..003934e72 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-lv.js @@ -0,0 +1,23 @@ +/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas <arturas.paleicikas@metasite.net> */ +jQuery(function($){ + $.datepicker.regional['lv'] = { + closeText: 'Aizvērt', + prevText: 'Iepr', + nextText: 'Nāka', + currentText: 'Šodien', + monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', + 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn', + 'Jūl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], + dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], + dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], + weekHeader: 'Nav', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lv']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-mk.js b/vendors/jquery/i18n/jquery.ui.datepicker-mk.js new file mode 100644 index 000000000..028532551 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-mk.js @@ -0,0 +1,23 @@ +/* Macedonian i18n for the jQuery UI date picker plugin. */ +/* Written by Stojce Slavkovski. */ +jQuery(function($){ + $.datepicker.regional['mk'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Денес', + monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', + 'Јули','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Ное','Дек'], + dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], + dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], + weekHeader: 'Сед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['mk']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ml.js b/vendors/jquery/i18n/jquery.ui.datepicker-ml.js new file mode 100644 index 000000000..1e3432c0a --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ml.js @@ -0,0 +1,23 @@ +/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Saji Nediyanchath (saji89@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ml'] = { + closeText: 'ശരി', + prevText: 'മുന്നത്തെ', + nextText: 'അടുത്തത് ', + currentText: 'ഇന്ന്', + monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്ച്ച്','ഏപ്രില്','മേയ്','ജൂണ്', + 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്','ഒക്ടോബര്','നവംബര്','ഡിസംബര്'], + monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്', 'ഏപ്രി', 'മേയ്', 'ജൂണ്', + 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'], + dayNames: ['ഞായര്', 'തിങ്കള്', 'ചൊവ്വ', 'ബുധന്', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'], + weekHeader: 'ആ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ml']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ms.js b/vendors/jquery/i18n/jquery.ui.datepicker-ms.js new file mode 100644 index 000000000..e953ac04f --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ms.js @@ -0,0 +1,23 @@ +/* Malaysian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ +jQuery(function($){ + $.datepicker.regional['ms'] = { + closeText: 'Tutup', + prevText: '<Sebelum', + nextText: 'Selepas>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Mac','April','Mei','Jun', + 'Julai','Ogos','September','Oktober','November','Disember'], + monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun', + 'Jul','Ogo','Sep','Okt','Nov','Dis'], + dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'], + dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'], + dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ms']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-nl-BE.js b/vendors/jquery/i18n/jquery.ui.datepicker-nl-BE.js new file mode 100644 index 000000000..7b3cdf425 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-nl-BE.js @@ -0,0 +1,23 @@ +/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ +/* David De Sloovere @DavidDeSloovere */ +jQuery(function($){ + $.datepicker.regional['nl-BE'] = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['nl-BE']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-nl.js b/vendors/jquery/i18n/jquery.ui.datepicker-nl.js new file mode 100644 index 000000000..781fe6191 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-nl.js @@ -0,0 +1,23 @@ +/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Mathias Bynens <http://mathiasbynens.be/> */ +jQuery(function($){ + $.datepicker.regional.nl = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional.nl); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-no.js b/vendors/jquery/i18n/jquery.ui.datepicker-no.js new file mode 100644 index 000000000..2507043a3 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-no.js @@ -0,0 +1,23 @@ +/* Norwegian initialisation for the jQuery UI date picker plugin. */ +/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ + +jQuery(function($){ + $.datepicker.regional['no'] = { + closeText: 'Lukk', + prevText: '«Forrige', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], + weekHeader: 'Uke', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + }; + $.datepicker.setDefaults($.datepicker.regional['no']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-pl.js b/vendors/jquery/i18n/jquery.ui.datepicker-pl.js new file mode 100644 index 000000000..61fa29ccd --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-pl.js @@ -0,0 +1,23 @@ +/* Polish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pl'] = { + closeText: 'Zamknij', + prevText: '<Poprzedni', + nextText: 'Następny>', + currentText: 'Dziś', + monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', + 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], + monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze', + 'Lip','Sie','Wrz','Pa','Lis','Gru'], + dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'], + dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], + dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], + weekHeader: 'Tydz', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pl']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-pt-BR.js b/vendors/jquery/i18n/jquery.ui.datepicker-pt-BR.js new file mode 100644 index 000000000..3cc8c796c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-pt-BR.js @@ -0,0 +1,23 @@ +/* Brazilian initialisation for the jQuery UI date picker plugin. */ +/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pt-BR'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Próximo>', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt-BR']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-pt.js b/vendors/jquery/i18n/jquery.ui.datepicker-pt.js new file mode 100644 index 000000000..f09f5aeb0 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-pt.js @@ -0,0 +1,22 @@ +/* Portuguese initialisation for the jQuery UI date picker plugin. */ +jQuery(function($){ + $.datepicker.regional['pt'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Seguinte', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sem', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-rm.js b/vendors/jquery/i18n/jquery.ui.datepicker-rm.js new file mode 100644 index 000000000..cf03cd4c1 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-rm.js @@ -0,0 +1,21 @@ +/* Romansh initialisation for the jQuery UI date picker plugin. */ +/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ +jQuery(function($){ + $.datepicker.regional['rm'] = { + closeText: 'Serrar', + prevText: '<Suandant', + nextText: 'Precedent>', + currentText: 'Actual', + monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], + monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], + dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], + dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], + dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], + weekHeader: 'emna', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['rm']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ro.js b/vendors/jquery/i18n/jquery.ui.datepicker-ro.js new file mode 100644 index 000000000..6b140aff6 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ro.js @@ -0,0 +1,26 @@ +/* Romanian initialisation for the jQuery UI date picker plugin. + * + * Written by Edmond L. (ll_edmond@walla.com) + * and Ionut G. Stan (ionut.g.stan@gmail.com) + */ +jQuery(function($){ + $.datepicker.regional['ro'] = { + closeText: 'Închide', + prevText: '« Luna precedentă', + nextText: 'Luna următoare »', + currentText: 'Azi', + monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie', + 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'], + monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', + 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], + dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'], + dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'], + weekHeader: 'Săpt', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ro']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ru.js b/vendors/jquery/i18n/jquery.ui.datepicker-ru.js new file mode 100644 index 000000000..50a461352 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ru.js @@ -0,0 +1,23 @@ +/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Andrew Stromnov (stromnov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ru'] = { + closeText: 'Закрыть', + prevText: '<Пред', + nextText: 'След>', + currentText: 'Сегодня', + monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', + 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], + dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], + dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Нед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ru']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-sk.js b/vendors/jquery/i18n/jquery.ui.datepicker-sk.js new file mode 100644 index 000000000..078d1b0fa --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-sk.js @@ -0,0 +1,23 @@ +/* Slovak initialisation for the jQuery UI date picker plugin. */ +/* Written by Vojtech Rinik (vojto@hmm.sk). */ +jQuery(function($){ + $.datepicker.regional['sk'] = { + closeText: 'Zavrieť', + prevText: '<Predchádzajúci', + nextText: 'Nasledujúci>', + currentText: 'Dnes', + monthNames: ['Január','Február','Marec','Apríl','Máj','Jún', + 'Júl','August','September','Október','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', + 'Júl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'], + dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], + dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], + weekHeader: 'Ty', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sk']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-sl.js b/vendors/jquery/i18n/jquery.ui.datepicker-sl.js new file mode 100644 index 000000000..516550192 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-sl.js @@ -0,0 +1,24 @@ +/* Slovenian initialisation for the jQuery UI date picker plugin. */ +/* Written by Jaka Jancar (jaka@kubje.org). */ +/* c = č, s = š z = ž C = Č S = Š Z = Ž */ +jQuery(function($){ + $.datepicker.regional['sl'] = { + closeText: 'Zapri', + prevText: '<Prejšnji', + nextText: 'Naslednji>', + currentText: 'Trenutni', + monthNames: ['Januar','Februar','Marec','April','Maj','Junij', + 'Julij','Avgust','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'], + dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'], + dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'], + weekHeader: 'Teden', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sl']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-sq.js b/vendors/jquery/i18n/jquery.ui.datepicker-sq.js new file mode 100644 index 000000000..21974c56c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-sq.js @@ -0,0 +1,23 @@ +/* Albanian initialisation for the jQuery UI date picker plugin. */ +/* Written by Flakron Bytyqi (flakron@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['sq'] = { + closeText: 'mbylle', + prevText: '<mbrapa', + nextText: 'Përpara>', + currentText: 'sot', + monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor', + 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'], + monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer', + 'Kor','Gus','Sht','Tet','Nën','Dhj'], + dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'], + dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'], + dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'], + weekHeader: 'Ja', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sq']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-sr-SR.js b/vendors/jquery/i18n/jquery.ui.datepicker-sr-SR.js new file mode 100644 index 000000000..e7a8683e4 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-sr-SR.js @@ -0,0 +1,23 @@ +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr-SR'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Jun', + 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Sed', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr-SR']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-sr.js b/vendors/jquery/i18n/jquery.ui.datepicker-sr.js new file mode 100644 index 000000000..0bd240e69 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-sr.js @@ -0,0 +1,23 @@ +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Данас', + monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун', + 'Јул','Август','Септембар','Октобар','Новембар','Децембар'], + monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Нов','Дец'], + dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'], + dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'], + dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'], + weekHeader: 'Сед', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-sv.js b/vendors/jquery/i18n/jquery.ui.datepicker-sv.js new file mode 100644 index 000000000..e5f549fbf --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-sv.js @@ -0,0 +1,23 @@ +/* Swedish initialisation for the jQuery UI date picker plugin. */ +/* Written by Anders Ekdahl ( anders@nomadiz.se). */ +jQuery(function($){ + $.datepicker.regional['sv'] = { + closeText: 'Stäng', + prevText: '«Förra', + nextText: 'Nästa»', + currentText: 'Idag', + monthNames: ['Januari','Februari','Mars','April','Maj','Juni', + 'Juli','Augusti','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'], + dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'], + dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], + weekHeader: 'Ve', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sv']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-ta.js b/vendors/jquery/i18n/jquery.ui.datepicker-ta.js new file mode 100644 index 000000000..40431ed8e --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-ta.js @@ -0,0 +1,23 @@ +/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by S A Sureshkumar (saskumar@live.com). */ +jQuery(function($){ + $.datepicker.regional['ta'] = { + closeText: 'மூடு', + prevText: 'முன்னையது', + nextText: 'அடுத்தது', + currentText: 'இன்று', + monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி', + 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'], + monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி', + 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'], + dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'], + dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'], + dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'], + weekHeader: 'Не', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ta']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-th.js b/vendors/jquery/i18n/jquery.ui.datepicker-th.js new file mode 100644 index 000000000..2e5300cfd --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-th.js @@ -0,0 +1,23 @@ +/* Thai initialisation for the jQuery UI date picker plugin. */ +/* Written by pipo (pipo@sixhead.com). */ +jQuery(function($){ + $.datepicker.regional['th'] = { + closeText: 'ปิด', + prevText: '« ย้อน', + nextText: 'ถัดไป »', + currentText: 'วันนี้', + monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', + 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], + monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', + 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], + dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], + dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['th']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-tj.js b/vendors/jquery/i18n/jquery.ui.datepicker-tj.js new file mode 100644 index 000000000..ed662392c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-tj.js @@ -0,0 +1,23 @@ +/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['tj'] = { + closeText: 'Идома', + prevText: '<Қафо', + nextText: 'Пеш>', + currentText: 'Имрӯз', + monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн', + 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'], + dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'], + dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'], + weekHeader: 'Хф', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tj']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-tr.js b/vendors/jquery/i18n/jquery.ui.datepicker-tr.js new file mode 100644 index 000000000..dedfc7ff9 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-tr.js @@ -0,0 +1,23 @@ +/* Turkish initialisation for the jQuery UI date picker plugin. */ +/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ +jQuery(function($){ + $.datepicker.regional['tr'] = { + closeText: 'kapat', + prevText: '<geri', + nextText: 'ileri>', + currentText: 'bugün', + monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', + 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'], + monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz', + 'Tem','Ağu','Eyl','Eki','Kas','Ara'], + dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'], + dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tr']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-uk.js b/vendors/jquery/i18n/jquery.ui.datepicker-uk.js new file mode 100644 index 000000000..2718f5d1c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-uk.js @@ -0,0 +1,24 @@ +/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ +/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['uk'] = { + closeText: 'Закрити', + prevText: '<', + nextText: '>', + currentText: 'Сьогодні', + monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень', + 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'], + monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер', + 'Лип','Сер','Вер','Жов','Лис','Гру'], + dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'], + dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'], + dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Тиж', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['uk']); +});
\ No newline at end of file diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-vi.js b/vendors/jquery/i18n/jquery.ui.datepicker-vi.js new file mode 100644 index 000000000..1d8f7bbd9 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-vi.js @@ -0,0 +1,23 @@ +/* Vietnamese initialisation for the jQuery UI date picker plugin. */ +/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ +jQuery(function($){ + $.datepicker.regional['vi'] = { + closeText: 'Đóng', + prevText: '<Trước', + nextText: 'Tiếp>', + currentText: 'Hôm nay', + monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', + 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'], + monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', + 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'], + dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'], + dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + weekHeader: 'Tu', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['vi']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-zh-CN.js b/vendors/jquery/i18n/jquery.ui.datepicker-zh-CN.js new file mode 100644 index 000000000..6c4883f53 --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-zh-CN.js @@ -0,0 +1,23 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Cloudream (cloudream@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-CN'] = { + closeText: '关闭', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一','二','三','四','五','六', + '七','八','九','十','十一','十二'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-CN']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-zh-HK.js b/vendors/jquery/i18n/jquery.ui.datepicker-zh-HK.js new file mode 100644 index 000000000..06c4c628c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-zh-HK.js @@ -0,0 +1,23 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by SCCY (samuelcychan@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-HK'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一','二','三','四','五','六', + '七','八','九','十','十一','十二'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-HK']); +}); diff --git a/vendors/jquery/i18n/jquery.ui.datepicker-zh-TW.js b/vendors/jquery/i18n/jquery.ui.datepicker-zh-TW.js new file mode 100644 index 000000000..dd51e359c --- /dev/null +++ b/vendors/jquery/i18n/jquery.ui.datepicker-zh-TW.js @@ -0,0 +1,23 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Ressol (ressol@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-TW'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一','二','三','四','五','六', + '七','八','九','十','十一','十二'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy/mm/dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-TW']); +}); diff --git a/version.php b/version.php index 0fb757b9c..77d151bb6 100644 --- a/version.php +++ b/version.php @@ -11,7 +11,7 @@ // YYYYMMDD = Elgg Date // XX = Interim incrementer -$version = 2012061800; +$version = 2012120500; // Human-friendly version name -$release = '1.8.6'; +$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/core/settings/statistics/numentities.php b/views/default/core/settings/statistics/numentities.php index ce1705a2e..3782fd8bc 100644 --- a/views/default/core/settings/statistics/numentities.php +++ b/views/default/core/settings/statistics/numentities.php @@ -7,7 +7,7 @@ */ // Get entity statistics -$entity_stats = get_entity_statistics(elgg_get_logged_in_user_guid()); +$entity_stats = get_entity_statistics(elgg_get_page_owner_guid()); if ($entity_stats) { $rows = ''; diff --git a/views/default/core/settings/statistics/online.php b/views/default/core/settings/statistics/online.php index ce7ff35fb..f50ad9acc 100644 --- a/views/default/core/settings/statistics/online.php +++ b/views/default/core/settings/statistics/online.php @@ -6,7 +6,7 @@ * @subpackage Core */ -$user = elgg_get_logged_in_user_entity(); +$user = elgg_get_page_owner_entity(); $logged_in = 0; $log = get_system_log($user->guid, "login", "", 'user', '', 1); diff --git a/views/default/css/admin.php b/views/default/css/admin.php index 0f5c1f677..059e51dd6 100644 --- a/views/default/css/admin.php +++ b/views/default/css/admin.php @@ -25,7 +25,6 @@ table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; - outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; @@ -41,9 +40,6 @@ img { border-width: 0; border-color: transparent; } -:focus { - outline: 0 none; -} ol, ul { list-style: none; } @@ -359,6 +355,8 @@ p { .elgg-table td, .elgg-table th { background: white; border: 1px solid #ccc; + padding: 4px 8px; + vertical-align: middle; } .elgg-table th { background-color: #ddd; @@ -366,10 +364,10 @@ p { .elgg-table .alt td { background: #eee; } -.elgg-table td { - padding: 4px 8px; - border-bottom: 1px solid #ccc; +.elgg-table input[type=checkbox] { + margin-top: 3px; } + .elgg-table-alt { width: 100%; border-top: 1px solid #ccc; @@ -441,7 +439,9 @@ input { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; + margin: 0; } + /* default elgg core input field classes */ .elgg-input-text, .elgg-input-tags, @@ -471,7 +471,6 @@ textarea { width: auto; padding: 2px 4px; cursor: pointer; - outline: none; } a.elgg-button { padding: 3px 6px; @@ -1239,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 { @@ -1461,7 +1464,8 @@ a.elgg-widget-collapsed:before { padding: 5px 10px; margin: 4px 0; } -ul.elgg-plugin-categories, ul.elgg-plugin-categories > li { +ul.elgg-plugin-categories, ul.elgg-plugin-categories > li, +ul.elgg-plugin-resources, ul.elgg-plugin-resources > li { display: inline; } .elgg-plugin-category-bundled { @@ -1511,6 +1515,12 @@ ul.elgg-plugin-categories, ul.elgg-plugin-categories > li { margin-bottom: 5px; } +.elgg-text-help { + display: block; + font-size: 85%; + font-style: italic; +} + .elgg-longtext-control { margin-left: 14px; font-size: 80%; diff --git a/views/default/forms/admin/site/update_advanced.php b/views/default/forms/admin/site/update_advanced.php index b935090f0..14b74e4f9 100644 --- a/views/default/forms/admin/site/update_advanced.php +++ b/views/default/forms/admin/site/update_advanced.php @@ -30,21 +30,21 @@ $form_body .= elgg_view('input/access', array( )) . "</div>"; $form_body .= "<div>" . elgg_echo('installation:allow_user_default_access:description') . "<br />"; $form_body .= elgg_view("input/checkboxes", array( - 'options' => array(elgg_echo('installation:allow_user_default_access:label') => elgg_echo('installation:allow_user_default_access:label')), + 'options' => array(elgg_echo('installation:allow_user_default_access:label') => 1), 'name' => 'allow_user_default_access', - 'value' => (elgg_get_config('allow_user_default_access') ? elgg_echo('installation:allow_user_default_access:label') : ""), + 'value' => (elgg_get_config('allow_user_default_access') ? 1 : 0), )) . "</div>"; $form_body .= "<div>" . elgg_echo('installation:simplecache:description') . "<br />"; $form_body .= elgg_view("input/checkboxes", array( - 'options' => array(elgg_echo('installation:simplecache:label') => elgg_echo('installation:simplecache:label')), + 'options' => array(elgg_echo('installation:simplecache:label') => 1), 'name' => 'simplecache_enabled', - 'value' => (elgg_get_config('simplecache_enabled') ? elgg_echo('installation:simplecache:label') : ""), + 'value' => (elgg_get_config('simplecache_enabled') ? 1 : 0), )) . "</div>"; $form_body .= "<div>" . elgg_echo('installation:systemcache:description') . "<br />"; $form_body .= elgg_view("input/checkboxes", array( - 'options' => array(elgg_echo('installation:systemcache:label') => elgg_echo('installation:systemcache:label')), + 'options' => array(elgg_echo('installation:systemcache:label') => 1), 'name' => 'system_cache_enabled', - 'value' => (elgg_get_config('system_cache_enabled') ? elgg_echo('installation:systemcache:label') : ""), + 'value' => (elgg_get_config('system_cache_enabled') ? 1 : 0), )) . "</div>"; $debug_options = array('0' => elgg_echo('installation:debug:none'), 'ERROR' => elgg_echo('installation:debug:error'), 'WARNING' => elgg_echo('installation:debug:warning'), 'NOTICE' => elgg_echo('installation:debug:notice')); @@ -58,9 +58,9 @@ $form_body .= '</div>'; // control new user registration $options = array( - 'options' => array(elgg_echo('installation:registration:label') => elgg_echo('installation:registration:label')), + 'options' => array(elgg_echo('installation:registration:label') => 1), 'name' => 'allow_registration', - 'value' => elgg_get_config('allow_registration') ? elgg_echo('installation:registration:label') : '', + 'value' => elgg_get_config('allow_registration') ? 1 : 0, ); $form_body .= '<div>' . elgg_echo('installation:registration:description'); $form_body .= '<br />' .elgg_view('input/checkboxes', $options) . '</div>'; @@ -68,28 +68,25 @@ $form_body .= '<br />' .elgg_view('input/checkboxes', $options) . '</div>'; // control walled garden $walled_garden = elgg_get_config(walled_garden); $options = array( - 'options' => array(elgg_echo('installation:walled_garden:label') => elgg_echo('installation:walled_garden:label')), + 'options' => array(elgg_echo('installation:walled_garden:label') => 1), 'name' => 'walled_garden', - 'value' => $walled_garden ? elgg_echo('installation:walled_garden:label') : '', + 'value' => $walled_garden ? 1 : 0, ); $form_body .= '<div>' . elgg_echo('installation:walled_garden:description'); $form_body .= '<br />' . elgg_view('input/checkboxes', $options) . '</div>'; $form_body .= "<div>" . elgg_echo('installation:httpslogin') . "<br />"; $form_body .= elgg_view("input/checkboxes", array( - 'options' => array(elgg_echo('installation:httpslogin:label') => elgg_echo('installation:httpslogin:label')), + 'options' => array(elgg_echo('installation:httpslogin:label') => 1), 'name' => 'https_login', - 'value' => (elgg_get_config('https_login') ? elgg_echo('installation:httpslogin:label') : "") + 'value' => (elgg_get_config('https_login') ? 1 : 0) )) . "</div>"; $form_body .= "<div>" . elgg_echo('installation:disableapi') . "<br />"; -$on = elgg_echo('installation:disableapi:label'); $disable_api = elgg_get_config('disable_api'); -if ($disable_api) { - $on = (disable_api ? "" : elgg_echo('installation:disableapi:label')); -} +$on = $disable_api ? 0 : 1; $form_body .= elgg_view("input/checkboxes", array( - 'options' => array(elgg_echo('installation:disableapi:label') => elgg_echo('installation:disableapi:label')), + 'options' => array(elgg_echo('installation:disableapi:label') => 1), 'name' => 'api', 'value' => $on, )); diff --git a/views/default/forms/profile/edit.php b/views/default/forms/profile/edit.php index 222935344..9538b779e 100644 --- a/views/default/forms/profile/edit.php +++ b/views/default/forms/profile/edit.php @@ -18,7 +18,8 @@ if (is_array($profile_fields) && count($profile_fields) > 0) { foreach ($profile_fields as $shortname => $valtype) { $metadata = elgg_get_metadata(array( 'guid' => $vars['entity']->guid, - 'metadata_name' => $shortname + 'metadata_name' => $shortname, + 'limit' => false )); if ($metadata) { if (is_array($metadata)) { 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/input/longtext.php b/views/default/input/longtext.php index 2b1462635..61dc7ca19 100644 --- a/views/default/input/longtext.php +++ b/views/default/input/longtext.php @@ -19,6 +19,8 @@ if (isset($vars['class'])) { $defaults = array( 'value' => '', + 'rows' => '10', + 'cols' => '50', 'id' => 'elgg-input-' . rand(), //@todo make this more robust ); diff --git a/views/default/input/plaintext.php b/views/default/input/plaintext.php index cd0aaafcf..e92c61ced 100644 --- a/views/default/input/plaintext.php +++ b/views/default/input/plaintext.php @@ -20,6 +20,8 @@ if (isset($vars['class'])) { $defaults = array( 'value' => '', + 'rows' => '10', + 'cols' => '50', 'disabled' => false, ); diff --git a/views/default/input/text.php b/views/default/input/text.php index 707a50179..07ce5c710 100644 --- a/views/default/input/text.php +++ b/views/default/input/text.php @@ -23,5 +23,4 @@ $defaults = array( $vars = array_merge($defaults, $vars); ?> - <input type="text" <?php echo elgg_format_attributes($vars); ?> />
\ No newline at end of file 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/languages.php b/views/default/js/languages.php index 009e8159c..c51d7bcb2 100644 --- a/views/default/js/languages.php +++ b/views/default/js/languages.php @@ -6,4 +6,10 @@ global $CONFIG; $language = $vars['language']; -echo json_encode($CONFIG->translations[$language]);
\ No newline at end of file +$translations = $CONFIG->translations['en']; + +if ($language != 'en') { + $translations = array_merge($translations, $CONFIG->translations[$language]); +} + +echo json_encode($translations);
\ No newline at end of file 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/object/plugin/elements/dependencies.php b/views/default/object/plugin/elements/dependencies.php index 8abd61692..d8daedd33 100644 --- a/views/default/object/plugin/elements/dependencies.php +++ b/views/default/object/plugin/elements/dependencies.php @@ -29,6 +29,8 @@ foreach ($deps as $dep) { if ($dep['status']) { $class = "elgg-state-success elgg-dependency elgg-dependency-$type"; + } elseif ($dep['type'] == 'suggests') { + $class = "elgg-state-warning elgg-dependency elgg-dependency-$type"; } else { $class = "elgg-state-error elgg-dependency elgg-dependency-$type"; } diff --git a/views/default/object/plugin/full.php b/views/default/object/plugin/full.php index db0a52416..2de65b555 100644 --- a/views/default/object/plugin/full.php +++ b/views/default/object/plugin/full.php @@ -172,6 +172,26 @@ $website = elgg_view('output/url', array( 'is_trusted' => true, )); +$resources = array( + 'repository' => $plugin->getManifest()->getRepositoryURL(), + 'bugtracker' => $plugin->getManifest()->getBugTrackerURL(), + 'donate' => $plugin->getManifest()->getDonationsPageURL(), +); + +$resources_html = "<ul class=\"elgg-plugin-resources\">"; +foreach ($resources as $id => $href) { + if ($href) { + $resources_html .= "<li class=\"prm\">"; + $resources_html .= elgg_view('output/url', array( + 'href' => $href, + 'text' => elgg_echo("admin:plugins:label:$id"), + 'is_trusted' => true, + )); + $resources_html .= "</li>"; + } +} +$resources_html .= "</ul>"; + $copyright = elgg_view('output/text', array('value' => $plugin->getManifest()->getCopyright())); $license = elgg_view('output/text', array('value' => $plugin->getManifest()->getLicense())); @@ -242,7 +262,11 @@ if (elgg_view_exists($settings_view_old) || elgg_view_exists($settings_view_new) <div><?php echo $description; ?></div> <p><?php echo $author . ' - ' . $website; ?></p> - <?php echo $docs; ?> + + <?php + echo $resources_html; + echo $docs; + ?> <div class="pts"> <?php @@ -281,4 +305,4 @@ if (elgg_view_exists($settings_view_old) || elgg_view_exists($settings_view_new) ?> </div> </div> -</div>
\ No newline at end of file +</div> 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/location.php b/views/default/output/location.php index e3619d2e1..e1009f17d 100644 --- a/views/default/output/location.php +++ b/views/default/output/location.php @@ -11,4 +11,9 @@ if (isset($vars['entity'])) { unset($vars['entity']); } +// Fixes #4566 we used to allow arrays of strings for location +if (is_array($vars['value'])) { + $vars['value'] = implode(', ', $vars['value']); +} + echo elgg_view('output/tag', $vars); 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/components/list.php b/views/default/page/components/list.php index 28c907ab6..0cf7d507c 100644 --- a/views/default/page/components/list.php +++ b/views/default/page/components/list.php @@ -6,7 +6,7 @@ * * @uses $vars['items'] Array of ElggEntity or ElggAnnotation objects * @uses $vars['offset'] Index of the first list item in complete list - * @uses $vars['limit'] Number of items per page + * @uses $vars['limit'] Number of items per page. Only used as input to pagination. * @uses $vars['count'] Number of items in the complete list * @uses $vars['base_url'] Base URL of list (optional) * @uses $vars['pagination'] Show pagination? (default: true) diff --git a/views/default/page/default.php b/views/default/page/default.php index 3724bffd8..567494d0c 100644 --- a/views/default/page/default.php +++ b/views/default/page/default.php @@ -33,9 +33,11 @@ $footer = elgg_view('page/elements/footer', $vars); // Set the content type header("Content-type: text/html; charset=UTF-8"); +$lang = get_current_language(); + ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang; ?>" lang="<?php echo $lang; ?>"> <head> <?php echo elgg_view('page/elements/head', $vars); ?> </head> @@ -45,13 +47,13 @@ header("Content-type: text/html; charset=UTF-8"); <?php echo $messages; ?> </div> - <?php if (elgg_is_logged_in()): ?> + <?php if (elgg_is_logged_in()){ ?> <div class="elgg-page-topbar"> <div class="elgg-inner"> <?php echo $topbar; ?> </div> </div> - <?php endif; ?> + <?php } ?> <div class="elgg-page-header"> <div class="elgg-inner"> diff --git a/views/default/page/elements/comments.php b/views/default/page/elements/comments.php index cf9b5f08b..97cb9574e 100644 --- a/views/default/page/elements/comments.php +++ b/views/default/page/elements/comments.php @@ -36,8 +36,7 @@ if ($html) { } if ($show_add_form) { - $form_vars = array('name' => 'elgg_add_comment'); - echo elgg_view_form('comments/add', $form_vars, $vars); + echo elgg_view_form('comments/add', array(), $vars); } echo '</div>'; diff --git a/views/default/page/elements/head.php b/views/default/page/elements/head.php index e968e95ce..1eb2be088 100644 --- a/views/default/page/elements/head.php +++ b/views/default/page/elements/head.php @@ -66,7 +66,9 @@ $release = get_version(true); <?php } ?> <script type="text/javascript"> +// <![CDATA[ <?php echo elgg_view('js/initialize_elgg'); ?> +// ]]> </script> <?php @@ -76,4 +78,4 @@ $metatags = elgg_view('metatags', $vars); if ($metatags) { elgg_deprecated_notice("The metatags view has been deprecated. Extend page/elements/head instead", 1.8); echo $metatags; -}
\ No newline at end of file +} 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/default/page/layouts/widgets.php b/views/default/page/layouts/widgets.php index e3819cc20..c6b162516 100644 --- a/views/default/page/layouts/widgets.php +++ b/views/default/page/layouts/widgets.php @@ -31,6 +31,7 @@ if (elgg_can_edit_widget_layout($context)) { 'widgets' => $widgets, 'context' => $context, 'exact_match' => $exact_match, + 'show_access' => $show_access, ); echo elgg_view('page/layouts/widgets/add_panel', $params); } diff --git a/views/default/page/layouts/widgets/add_panel.php b/views/default/page/layouts/widgets/add_panel.php index 9eb78cdb6..d9b11342a 100644 --- a/views/default/page/layouts/widgets/add_panel.php +++ b/views/default/page/layouts/widgets/add_panel.php @@ -50,10 +50,13 @@ foreach ($widgets as $column_widgets) { ?> </ul> <?php - $params = array( + echo elgg_view('input/hidden', array( 'name' => 'widget_context', 'value' => $context - ); - echo elgg_view('input/hidden', $params); + )); + echo elgg_view('input/hidden', array( + 'name' => 'show_access', + 'value' => (int)$vars['show_access'] + )); ?> </div> diff --git a/views/default/widgets/new_users/content.php b/views/default/widgets/new_users/content.php index 207a67a9d..ba85e7421 100644 --- a/views/default/widgets/new_users/content.php +++ b/views/default/widgets/new_users/content.php @@ -6,5 +6,6 @@ echo elgg_list_entities(array( 'type' => 'user', 'subtype'=> null, - 'full_view' => FALSE + 'full_view' => false, + 'pagination' => false, ));
\ No newline at end of file diff --git a/views/default/widgets/online_users/content.php b/views/default/widgets/online_users/content.php index d81ff3705..6e0cc7abb 100644 --- a/views/default/widgets/online_users/content.php +++ b/views/default/widgets/online_users/content.php @@ -3,4 +3,13 @@ * Online users widget */ -echo $users_online = get_online_users();
\ No newline at end of file +$count = find_active_users(600, 10, 0, true); +$objects = find_active_users(600, 10); + +if ($objects) { + echo elgg_view_entity_list($objects, array( + 'count' => $count, + 'limit' => 10, + 'pagination' => false, + )); +} diff --git a/views/installation/install/js_rewrite_check.php b/views/installation/install/js_rewrite_check.php new file mode 100644 index 000000000..04d81171d --- /dev/null +++ b/views/installation/install/js_rewrite_check.php @@ -0,0 +1,12 @@ +<?php +/** + * Some servers don't allow PHP to check the rewrite, so try via AJAX + */ +?> +<script type="text/javascript"> + elgg.installer.rewriteTest( + '<?php echo $vars['url'];?>', + '<?php echo elgg_echo('install:check:rewrite:success'); ?>', + '<?php echo $vars['config']->wwwroot; ?>install.php?step=database' + ); +</script>
\ No newline at end of file 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..3f0941c95 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,17 +23,17 @@ 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>"; } -$vars['refresh'] = TRUE; +$vars['refresh'] = true; // cannot advance to next step with a failure if ($vars['num_failures'] != 0) { - $vars['advance'] = FALSE; + $vars['advance'] = false; } echo elgg_view('install/nav', $vars); 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')) { ?> |