/** * Return the most recent error message for the database connector. * * @param boolean $showSQL True to display the SQL statement sent to the database as well as the error. * * @return string The error message for the most recent query. * * @since 11.1 * @deprecated 13.3 */ public function stderr($showSQL = false) { Log::add('JDatabase::stderr() is deprecated.', Log::WARNING, 'deprecated'); if ($this->errorNum != 0) { return Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $this->errorNum, $this->errorMsg) . ($showSQL ? "<br />SQL = <pre>{$this->sql}</pre>" : ''); } else { return Text::_('JLIB_DATABASE_FUNCTION_NOERROR'); } }
/** * Method to get a stemmer, creating it if necessary. * * @param string $adapter The type of stemmer to load. * * @return Stemmer A JLanguageStemmer instance. * * @since 12.1 * @throws RuntimeException on invalid stemmer. */ public static function getInstance($adapter) { // Only create one stemmer for each adapter. if (isset(self::$instances[$adapter])) { return self::$instances[$adapter]; } // Setup the adapter for the stemmer. $class = '\\Joomla\\Language\\Stemmer\\' . ucfirst(trim($adapter)); // Check if a stemmer exists for the adapter. if (!class_exists($class)) { // Throw invalid adapter exception. throw new RuntimeException(Text::sprintf('JLIB_STEMMER_INVALID_STEMMER', $adapter)); } self::$instances[$adapter] = new $class(); return self::$instances[$adapter]; }
/** * Sends mail to administrator for approval of a user submission * * @param string $adminName Name of administrator * @param string $adminEmail Email address of administrator * @param string $email [NOT USED TODO: Deprecate?] * @param string $type Type of item to approve * @param string $title Title of item to approve * @param string $author Author of item to approve * @param string $url A URL to included in the mail * * @return boolean True on success * * @since 11.1 */ public function sendAdminMail($adminName, $adminEmail, $email, $type, $title, $author, $url = null) { $subject = Text::sprintf('JLIB_MAIL_USER_SUBMITTED', $type); $message = sprintf(Text::_('JLIB_MAIL_MSG_ADMIN'), $adminName, $type, $title, $author, $url, $url, 'administrator', $type); $message .= Text::_('JLIB_MAIL_MSG') . "\n"; $this->addRecipient($adminEmail); $this->setSubject($subject); $this->setBody($message); return $this->Send(); }
/** * Execute the SQL statement. * * @return mixed A database cursor resource on success, boolean false on failure. * * @since 12.1 * @throws RuntimeException */ public function execute() { $this->connect(); if (!is_resource($this->connection)) { Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'database'); throw new RuntimeException($this->errorMsg, $this->errorNum); } // Take a local copy so that we don't modify the original query and cause issues later $sql = $this->replacePrefix((string) $this->sql); if ($this->limit > 0 || $this->offset > 0) { $sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit; } // Increment the query counter. $this->count++; // If debugging is enabled then let's log the query. if ($this->debug) { // Add the query to the object queue. $this->log[] = $sql; Log::add($sql, Log::DEBUG, 'databasequery'); } // Reset the error values. $this->errorNum = 0; $this->errorMsg = ''; // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost. $this->cursor = @mysql_query($sql, $this->connection); // If an error occurred handle it. if (!$this->cursor) { // Check if the server was disconnected. if (!$this->connected()) { try { // Attempt to reconnect. $this->connection = null; $this->connect(); } catch (RuntimeException $e) { // Get the error number and message. $this->errorNum = (int) mysql_errno($this->connection); $this->errorMsg = (string) mysql_error($this->connection) . ' SQL=' . $sql; // Throw the normal query exception. Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'databasequery'); throw new RuntimeException($this->errorMsg, $this->errorNum); } // Since we were able to reconnect, run the query again. return $this->execute(); } else { // Get the error number and message. $this->errorNum = (int) mysql_errno($this->connection); $this->errorMsg = (string) mysql_error($this->connection) . ' SQL=' . $sql; // Throw the normal query exception. Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'databasequery'); throw new RuntimeException($this->errorMsg, $this->errorNum); } } return $this->cursor; }
/** * Parses a language file. * * @param string $filename The name of the file. * * @return array The array of parsed strings. * * @since 11.1 */ protected function parse($filename) { if ($this->debug) { // Capture hidden PHP errors from the parsing. $php_errormsg = null; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); } $contents = file_get_contents($filename); $contents = str_replace('_QQ_', '"\\""', $contents); $strings = @parse_ini_string($contents); if (!is_array($strings)) { $strings = array(); } if ($this->debug) { // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); // Initialise variables for manually parsing the file for common errors. $blacklist = array('YES', 'NO', 'NULL', 'FALSE', 'ON', 'OFF', 'NONE', 'TRUE'); $regex = '/^(|(\\[[^\\]]*\\])|([A-Z][A-Z0-9_\\-\\.]*\\s*=(\\s*(("[^"]*")|(_QQ_)))+))\\s*(;.*)?$/'; $this->debug = false; $errors = array(); // Open the file as a stream. $file = new SplFileObject($filename); foreach ($file as $lineNumber => $line) { // Avoid BOM error as BOM is OK when using parse_ini if ($lineNumber == 0) { $line = str_replace("", '', $line); } // Check that the key is not in the blacklist and that the line format passes the regex. $key = strtoupper(trim(substr($line, 0, strpos($line, '=')))); // Workaround to reduce regex complexity when matching escaped quotes $line = str_replace('\\"', '_QQ_', $line); if (!preg_match($regex, $line) || in_array($key, $blacklist)) { $errors[] = $lineNumber; } } // Check if we encountered any errors. if (count($errors)) { if (basename($filename) != $this->lang . '.ini') { $this->errorfiles[$filename] = $filename . Text::sprintf('JERROR_PARSING_LANGUAGE_FILE', implode(', ', $errors)); } else { $this->errorfiles[$filename] = $filename . ' : error(s) in line(s) ' . implode(', ', $errors); } } elseif ($php_errormsg) { // We didn't find any errors but there's probably a parse notice. $this->errorfiles['PHP' . $filename] = 'PHP parser errors :' . $php_errormsg; } $this->debug = true; } return $strings; }
/** * Render the feed. * * @param string $name The name of the element to render * @param array $params Array of values * @param string $content Override the output of the renderer * * @return string The output of the script * * @see JDocumentRenderer::render() * @since 11.1 */ public function render($name = '', $params = null, $content = null) { $app = Factory::getApplication(); // Gets and sets timezone offset from site configuration $tz = new DateTimeZone($app->getCfg('offset')); $now = Factory::getDate(); $now->setTimeZone($tz); $data = $this->_doc; $uri = Uri::getInstance(); $url = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port')); $syndicationURL = Route::_('&format=feed&type=atom'); if ($app->getCfg('sitename_pagetitles', 0) == 1) { $title = Text::sprintf('JPAGETITLE', $app->getCfg('sitename'), $data->title); } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) { $title = Text::sprintf('JPAGETITLE', $data->title, $app->getCfg('sitename')); } else { $title = $data->title; } $feed_title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); $feed = "<feed xmlns=\"http://www.w3.org/2005/Atom\" "; if ($data->language != "") { $feed .= " xml:lang=\"" . $data->language . "\""; } $feed .= ">\n"; $feed .= "\t<title type=\"text\">" . $feed_title . "</title>\n"; $feed .= "\t<subtitle type=\"text\">" . htmlspecialchars($data->description, ENT_COMPAT, 'UTF-8') . "</subtitle>\n"; if (empty($data->category) === false) { if (is_array($data->category)) { foreach ($data->category as $cat) { $feed .= "\t<category term=\"" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "\" />\n"; } } else { $feed .= "\t<category term=\"" . htmlspecialchars($data->category, ENT_COMPAT, 'UTF-8') . "\" />\n"; } } $feed .= "\t<link rel=\"alternate\" type=\"text/html\" href=\"" . $url . "\"/>\n"; $feed .= "\t<id>" . str_replace(' ', '%20', $data->getBase()) . "</id>\n"; $feed .= "\t<updated>" . htmlspecialchars($now->toISO8601(true), ENT_COMPAT, 'UTF-8') . "</updated>\n"; if ($data->editor != "") { $feed .= "\t<author>\n"; $feed .= "\t\t<name>" . $data->editor . "</name>\n"; if ($data->editorEmail != "") { $feed .= "\t\t<email>" . htmlspecialchars($data->editorEmail, ENT_COMPAT, 'UTF-8') . "</email>\n"; } $feed .= "\t</author>\n"; } $feed .= "\t<generator uri=\"http://joomla.org\" version=\"1.6\">" . $data->getGenerator() . "</generator>\n"; $feed .= ' <link rel="self" type="application/atom+xml" href="' . str_replace(' ', '%20', $url . $syndicationURL) . "\"/>\n"; for ($i = 0, $count = count($data->items); $i < $count; $i++) { $feed .= "\t<entry>\n"; $feed .= "\t\t<title>" . htmlspecialchars(strip_tags($data->items[$i]->title), ENT_COMPAT, 'UTF-8') . "</title>\n"; $feed .= ' <link rel="alternate" type="text/html" href="' . $url . $data->items[$i]->link . "\"/>\n"; if ($data->items[$i]->date == "") { $data->items[$i]->date = $now->toUnix(); } $itemDate = Factory::getDate($data->items[$i]->date); $itemDate->setTimeZone($tz); $feed .= "\t\t<published>" . htmlspecialchars($itemDate->toISO8601(true), ENT_COMPAT, 'UTF-8') . "</published>\n"; $feed .= "\t\t<updated>" . htmlspecialchars($itemDate->toISO8601(true), ENT_COMPAT, 'UTF-8') . "</updated>\n"; if (empty($data->items[$i]->guid) === true) { $feed .= "\t\t<id>" . str_replace(' ', '%20', $url . $data->items[$i]->link) . "</id>\n"; } else { $feed .= "\t\t<id>" . htmlspecialchars($data->items[$i]->guid, ENT_COMPAT, 'UTF-8') . "</id>\n"; } if ($data->items[$i]->author != "") { $feed .= "\t\t<author>\n"; $feed .= "\t\t\t<name>" . htmlspecialchars($data->items[$i]->author, ENT_COMPAT, 'UTF-8') . "</name>\n"; if ($data->items[$i]->authorEmail != "") { $feed .= "\t\t\t<email>" . htmlspecialchars($data->items[$i]->authorEmail, ENT_COMPAT, 'UTF-8') . "</email>\n"; } $feed .= "\t\t</author>\n"; } if ($data->items[$i]->description != "") { $feed .= "\t\t<summary type=\"html\">" . htmlspecialchars($data->items[$i]->description, ENT_COMPAT, 'UTF-8') . "</summary>\n"; $feed .= "\t\t<content type=\"html\">" . htmlspecialchars($data->items[$i]->description, ENT_COMPAT, 'UTF-8') . "</content>\n"; } if (empty($data->items[$i]->category) === false) { if (is_array($data->items[$i]->category)) { foreach ($data->items[$i]->category as $cat) { $feed .= "\t\t<category term=\"" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "\" />\n"; } } else { $feed .= "\t\t<category term=\"" . htmlspecialchars($data->items[$i]->category, ENT_COMPAT, 'UTF-8') . "\" />\n"; } } if ($data->items[$i]->enclosure != null) { $feed .= "\t\t<link rel=\"enclosure\" href=\"" . $data->items[$i]->enclosure->url . "\" type=\"" . $data->items[$i]->enclosure->type . "\" length=\"" . $data->items[$i]->enclosure->length . "\" />\n"; } $feed .= "\t</entry>\n"; } $feed .= "</feed>\n"; return $feed; }
/** * Utility function to read the folders in a folder. * * @param string $path The path of the folder to read. * @param string $filter A filter for folder names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $fullpath True to return the full path to the folders. * @param array $exclude Array with names of folders which should not be shown in the result. * @param array $excludefilter Array with regular expressions matching folders which should not be shown in the result. * * @return array Folders in the given folder. * * @since 11.1 */ protected function _folders($path, $filter = '.', $recurse = false, $fullpath = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludefilter = array('^\\..*')) { $arr = array(); // Check to make sure the path valid and clean $path = $this->_cleanPath($path); // Is the path a folder? if (!is_dir($path)) { Log::add('\\Joomla\\Cache\\Storage\\File::_folders' . Text::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER', $path), Log::WARNING, 'jerror'); return false; } // Read the source directory if (!($handle = @opendir($path))) { return $arr; } if (count($excludefilter)) { $excludefilter_string = '/(' . implode('|', $excludefilter) . ')/'; } else { $excludefilter_string = ''; } while (($file = readdir($handle)) !== false) { if ($file != '.' && $file != '..' && !in_array($file, $exclude) && (empty($excludefilter_string) || !preg_match($excludefilter_string, $file))) { $dir = $path . '/' . $file; $isDir = is_dir($dir); if ($isDir) { // Removes filtered directories if (preg_match("/{$filter}/", $file)) { if ($fullpath) { $arr[] = $dir; } else { $arr[] = $file; } } if ($recurse) { if (is_int($recurse)) { $arr2 = $this->_folders($dir, $filter, $recurse - 1, $fullpath, $exclude, $excludefilter); } else { $arr2 = $this->_folders($dir, $filter, $recurse, $fullpath, $exclude, $excludefilter); } $arr = array_merge($arr, $arr2); } } } } closedir($handle); return $arr; }
/** * Creates the HTML for the permissions widget * * @param array $actions Array of action objects * @param integer $assetId Id of a specific asset to create a widget for. * @param integer $parent Id of the parent of the asset * @param string $control The form control * @param string $idPrefix Prefix for the ids assigned to specific action-group pairs * * @return string HTML for the permissions widget * * @since 11.1 * * @see JAccess * @see JFormFieldRules */ public static function assetFormWidget($actions, $assetId = null, $parent = null, $control = 'jform[rules]', $idPrefix = 'jform_rules') { $images = self::_getImagesArray(); // Get the user groups. $groups = self::_getUserGroups(); // Get the incoming inherited rules as well as the asset specific rules. $inheriting = Access::getAssetRules($parent ? $parent : self::_getParentAssetId($assetId), true); $inherited = Access::getAssetRules($assetId, true); $rules = Access::getAssetRules($assetId); $html = array(); $html[] = '<div class="acl-options">'; $html[] = Html::_('tabs.start', 'acl-rules-' . $assetId, array('useCookie' => 1)); $html[] = Html::_('tabs.panel', Text::_('JLIB_HTML_ACCESS_SUMMARY'), 'summary'); $html[] = ' <p>' . Text::_('JLIB_HTML_ACCESS_SUMMARY_DESC') . '</p>'; $html[] = ' <table class="aclsummary-table" summary="' . Text::_('JLIB_HTML_ACCESS_SUMMARY_DESC') . '">'; $html[] = ' <caption>' . Text::_('JLIB_HTML_ACCESS_SUMMARY_DESC_CAPTION') . '</caption>'; $html[] = ' <tr>'; $html[] = ' <th class="col1 hidelabeltxt">' . Text::_('JLIB_RULES_GROUPS') . '</th>'; foreach ($actions as $i => $action) { $html[] = ' <th class="col' . ($i + 2) . '">' . Text::_($action->title) . '</th>'; } $html[] = ' </tr>'; foreach ($groups as $i => $group) { $html[] = ' <tr class="row' . $i % 2 . '">'; $html[] = ' <td class="col1">' . $group->text . '</td>'; foreach ($actions as $j => $action) { $html[] = ' <td class="col' . ($j + 2) . '">' . ($assetId ? $inherited->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'] : ($inheriting->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])) . '</td>'; } $html[] = ' </tr>'; } $html[] = ' </table>'; foreach ($actions as $action) { $actionTitle = Text::_($action->title); $actionDesc = Text::_($action->description); $html[] = Html::_('tabs.panel', $actionTitle, $action->name); $html[] = ' <p>' . $actionDesc . '</p>'; $html[] = ' <table class="aclmodify-table" summary="' . strip_tags($actionDesc) . '">'; $html[] = ' <caption>' . Text::_('JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_ACL') . ' ' . $actionTitle . ' ' . Text::_('JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_TABLE') . '</caption>'; $html[] = ' <tr>'; $html[] = ' <th class="col1 hidelabeltxt">' . Text::_('JLIB_RULES_GROUP') . '</th>'; $html[] = ' <th class="col2">' . Text::_('JLIB_RULES_INHERIT') . '</th>'; $html[] = ' <th class="col3 hidelabeltxt">' . Text::_('JMODIFY') . '</th>'; $html[] = ' <th class="col4">' . Text::_('JCURRENT') . '</th>'; $html[] = ' </tr>'; foreach ($groups as $i => $group) { $selected = $rules->allow($action->name, $group->value); $html[] = ' <tr class="row' . $i % 2 . '">'; $html[] = ' <td class="col1">' . $group->text . '</td>'; $html[] = ' <td class="col2">' . ($inheriting->allow($action->name, $group->identities) ? $images['allow-i'] : $images['deny-i']) . '</td>'; $html[] = ' <td class="col3">'; $html[] = ' <select id="' . $idPrefix . '_' . $action->name . '_' . $group->value . '" class="inputbox" size="1" name="' . $control . '[' . $action->name . '][' . $group->value . ']" title="' . Text::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', $actionTitle, $group->text) . '">'; $html[] = ' <option value=""' . ($selected === null ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_INHERIT') . '</option>'; $html[] = ' <option value="1"' . ($selected === true ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_ALLOWED') . '</option>'; $html[] = ' <option value="0"' . ($selected === false ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_DENIED') . '</option>'; $html[] = ' </select>'; $html[] = ' </td>'; $html[] = ' <td class="col4">' . ($assetId ? $inherited->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'] : ($inheriting->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])) . '</td>'; $html[] = ' </tr>'; } $html[] = ' </table>'; } $html[] = Html::_('tabs.end'); // Build the footer with legend and special purpose buttons. $html[] = ' <div class="clr"></div>'; $html[] = ' <ul class="acllegend fltlft">'; $html[] = ' <li class="acl-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</li>'; $html[] = ' <li class="acl-denied">' . Text::_('JLIB_RULES_DENIED') . '</li>'; $html[] = ' </ul>'; $html[] = '</div>'; return implode("\n", $html); }
/** * Method to create a checkbox for a grid row. * * @param integer $rowNum The row index * @param integer $recId The record id * @param boolean $checkedOut True if item is checke out * @param string $name The name of the form element * * @return mixed String of html with a checkbox if item is not checked out, null if checked out. */ public static function id($rowNum, $recId, $checkedOut = false, $name = 'cid') { if ($checkedOut) { return ''; } else { return '<input type="checkbox" id="cb' . $rowNum . '" name="' . $name . '[]" value="' . $recId . '" onclick="Joomla.isChecked(this.checked);" title="' . Text::sprintf('JGRID_CHECKBOX_ROW_N', $rowNum + 1) . '" />'; } }
/** * Execute the SQL statement. * * @return mixed A database cursor resource on success, boolean false on failure. * * @since 12.1 * @throws RuntimeException * @throws Exception */ public function execute() { $this->connect(); if (!is_object($this->connection)) { Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'database'); throw new RuntimeException($this->errorMsg, $this->errorNum); } // Take a local copy so that we don't modify the original query and cause issues later $sql = $this->replacePrefix((string) $this->sql); if ($this->limit > 0 || $this->offset > 0) { // @TODO $sql .= ' LIMIT ' . $this->offset . ', ' . $this->limit; } // Increment the query counter. $this->count++; // If debugging is enabled then let's log the query. if ($this->debug) { // Add the query to the object queue. $this->log[] = $sql; Log::add($sql, Log::DEBUG, 'databasequery'); } // Reset the error values. $this->errorNum = 0; $this->errorMsg = ''; // Execute the query. $this->executed = false; if ($this->prepared instanceof PDOStatement) { // Bind the variables: if ($this->sql instanceof Preparable) { $bounded =& $this->sql->getBounded(); foreach ($bounded as $key => $obj) { $this->prepared->bindParam($key, $obj->value, $obj->dataType, $obj->length, $obj->driverOptions); } } $this->executed = $this->prepared->execute(); } // If an error occurred handle it. if (!$this->executed) { // Get the error number and message before we execute any more queries. $errorNum = (int) $this->connection->errorCode(); $errorMsg = (string) 'SQL: ' . implode(", ", $this->connection->errorInfo()); // Check if the server was disconnected. if (!$this->connected()) { try { // Attempt to reconnect. $this->connection = null; $this->connect(); } catch (RuntimeException $e) { // Get the error number and message. $this->errorNum = (int) $this->connection->errorCode(); $this->errorMsg = (string) 'SQL: ' . implode(", ", $this->connection->errorInfo()); // Throw the normal query exception. Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'databasequery'); throw new RuntimeException($this->errorMsg, $this->errorNum); } // Since we were able to reconnect, run the query again. return $this->execute(); } else { // Get the error number and message from before we tried to reconnect. $this->errorNum = $errorNum; $this->errorMsg = $errorMsg; // Throw the normal query exception. Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'databasequery'); throw new RuntimeException($this->errorMsg, $this->errorNum); } } return $this->prepared; }
/** * Render the feed. * * @param string $name The name of the element to render * @param array $params Array of values * @param string $content Override the output of the renderer * * @return string The output of the script * * @see JDocumentRenderer::render() * @since 11.1 */ public function render($name = '', $params = null, $content = null) { $app = Factory::getApplication(); // Gets and sets timezone offset from site configuration $tz = new DateTimeZone($app->getCfg('offset')); $now = Factory::getDate(); $now->setTimeZone($tz); $data = $this->_doc; $uri = Uri::getInstance(); $url = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port')); $syndicationURL = Route::_('&format=feed&type=rss'); if ($app->getCfg('sitename_pagetitles', 0) == 1) { $title = Text::sprintf('JPAGETITLE', $app->getCfg('sitename'), $data->title); } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) { $title = Text::sprintf('JPAGETITLE', $data->title, $app->getCfg('sitename')); } else { $title = $data->title; } $feed_title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); $feed = "<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n"; $feed .= "\t<channel>\n"; $feed .= "\t\t<title>" . $feed_title . "</title>\n"; $feed .= "\t\t<description><![CDATA[" . $data->description . "]]></description>\n"; $feed .= "\t\t<link>" . str_replace(' ', '%20', $url . $data->link) . "</link>\n"; $feed .= "\t\t<lastBuildDate>" . htmlspecialchars($now->toRFC822(true), ENT_COMPAT, 'UTF-8') . "</lastBuildDate>\n"; $feed .= "\t\t<generator>" . $data->getGenerator() . "</generator>\n"; $feed .= ' <atom:link rel="self" type="application/rss+xml" href="' . str_replace(' ', '%20', $url . $syndicationURL) . "\"/>\n"; if ($data->image != null) { $feed .= "\t\t<image>\n"; $feed .= "\t\t\t<url>" . $data->image->url . "</url>\n"; $feed .= "\t\t\t<title>" . htmlspecialchars($data->image->title, ENT_COMPAT, 'UTF-8') . "</title>\n"; $feed .= "\t\t\t<link>" . str_replace(' ', '%20', $data->image->link) . "</link>\n"; if ($data->image->width != "") { $feed .= "\t\t\t<width>" . $data->image->width . "</width>\n"; } if ($data->image->height != "") { $feed .= "\t\t\t<height>" . $data->image->height . "</height>\n"; } if ($data->image->description != "") { $feed .= "\t\t\t<description><![CDATA[" . $data->image->description . "]]></description>\n"; } $feed .= "\t\t</image>\n"; } if ($data->language != "") { $feed .= "\t\t<language>" . $data->language . "</language>\n"; } if ($data->copyright != "") { $feed .= "\t\t<copyright>" . htmlspecialchars($data->copyright, ENT_COMPAT, 'UTF-8') . "</copyright>\n"; } if ($data->editorEmail != "") { $feed .= "\t\t<managingEditor>" . htmlspecialchars($data->editorEmail, ENT_COMPAT, 'UTF-8') . ' (' . htmlspecialchars($data->editor, ENT_COMPAT, 'UTF-8') . ")</managingEditor>\n"; } if ($data->webmaster != "") { $feed .= "\t\t<webMaster>" . htmlspecialchars($data->webmaster, ENT_COMPAT, 'UTF-8') . "</webMaster>\n"; } if ($data->pubDate != "") { $pubDate = JFactory::getDate($data->pubDate); $pubDate->setTimeZone($tz); $feed .= "\t\t<pubDate>" . htmlspecialchars($pubDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "</pubDate>\n"; } if (empty($data->category) === false) { if (is_array($data->category)) { foreach ($data->category as $cat) { $feed .= "\t\t<category>" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "</category>\n"; } } else { $feed .= "\t\t<category>" . htmlspecialchars($data->category, ENT_COMPAT, 'UTF-8') . "</category>\n"; } } if ($data->docs != "") { $feed .= "\t\t<docs>" . htmlspecialchars($data->docs, ENT_COMPAT, 'UTF-8') . "</docs>\n"; } if ($data->ttl != "") { $feed .= "\t\t<ttl>" . htmlspecialchars($data->ttl, ENT_COMPAT, 'UTF-8') . "</ttl>\n"; } if ($data->rating != "") { $feed .= "\t\t<rating>" . htmlspecialchars($data->rating, ENT_COMPAT, 'UTF-8') . "</rating>\n"; } if ($data->skipHours != "") { $feed .= "\t\t<skipHours>" . htmlspecialchars($data->skipHours, ENT_COMPAT, 'UTF-8') . "</skipHours>\n"; } if ($data->skipDays != "") { $feed .= "\t\t<skipDays>" . htmlspecialchars($data->skipDays, ENT_COMPAT, 'UTF-8') . "</skipDays>\n"; } for ($i = 0, $count = count($data->items); $i < $count; $i++) { if (strpos($data->items[$i]->link, 'http://') === false && strpos($data->items[$i]->link, 'https://') === false) { $data->items[$i]->link = str_replace(' ', '%20', $url . $data->items[$i]->link); } $feed .= "\t\t<item>\n"; $feed .= "\t\t\t<title>" . htmlspecialchars(strip_tags($data->items[$i]->title), ENT_COMPAT, 'UTF-8') . "</title>\n"; $feed .= "\t\t\t<link>" . str_replace(' ', '%20', $data->items[$i]->link) . "</link>\n"; if (empty($data->items[$i]->guid) === true) { $feed .= "\t\t\t<guid isPermaLink=\"true\">" . str_replace(' ', '%20', $data->items[$i]->link) . "</guid>\n"; } else { $feed .= "\t\t\t<guid isPermaLink=\"false\">" . htmlspecialchars($data->items[$i]->guid, ENT_COMPAT, 'UTF-8') . "</guid>\n"; } $feed .= "\t\t\t<description><![CDATA[" . $this->_relToAbs($data->items[$i]->description) . "]]></description>\n"; if ($data->items[$i]->authorEmail != "") { $feed .= "\t\t\t<author>" . htmlspecialchars($data->items[$i]->authorEmail . ' (' . $data->items[$i]->author . ')', ENT_COMPAT, 'UTF-8') . "</author>\n"; } /* * @todo: On hold * if ($data->items[$i]->source!="") { * $data.= " <source>".htmlspecialchars($data->items[$i]->source, ENT_COMPAT, 'UTF-8')."</source>\n"; * } */ if (empty($data->items[$i]->category) === false) { if (is_array($data->items[$i]->category)) { foreach ($data->items[$i]->category as $cat) { $feed .= "\t\t\t<category>" . htmlspecialchars($cat, ENT_COMPAT, 'UTF-8') . "</category>\n"; } } else { $feed .= "\t\t\t<category>" . htmlspecialchars($data->items[$i]->category, ENT_COMPAT, 'UTF-8') . "</category>\n"; } } if ($data->items[$i]->comments != "") { $feed .= "\t\t\t<comments>" . htmlspecialchars($data->items[$i]->comments, ENT_COMPAT, 'UTF-8') . "</comments>\n"; } if ($data->items[$i]->date != "") { $itemDate = Factory::getDate($data->items[$i]->date); $itemDate->setTimeZone($tz); $feed .= "\t\t\t<pubDate>" . htmlspecialchars($itemDate->toRFC822(true), ENT_COMPAT, 'UTF-8') . "</pubDate>\n"; } if ($data->items[$i]->enclosure != null) { $feed .= "\t\t\t<enclosure url=\""; $feed .= $data->items[$i]->enclosure->url; $feed .= "\" length=\""; $feed .= $data->items[$i]->enclosure->length; $feed .= "\" type=\""; $feed .= $data->items[$i]->enclosure->type; $feed .= "\"/>\n"; } $feed .= "\t\t</item>\n"; } $feed .= "\t</channel>\n"; $feed .= "</rss>\n"; return $feed; }
/** * Test... * * @covers Joomla\Language\Text::sprintf * * @return void * * @since 1.1.2 */ public function testSprintf() { $string = "foobar's"; $output = Text::sprintf($string); $this->assertEquals($string, $output); $nStrings = count(TestHelper::getValue($this->object, 'strings')); $options = array('jsSafe' => true); $output = Text::sprintf($string, $options); $this->assertEquals("foobar\\'s", $output); $this->assertCount($nStrings, TestHelper::getValue($this->object, 'strings')); $nStrings = count(TestHelper::getValue($this->object, 'strings')); $options = array('script' => true); $output = Text::sprintf($string, $options); $this->assertEquals("foobar's", $output); $this->assertCount($nStrings + 1, TestHelper::getValue($this->object, 'strings')); }
/** * Set transfer mode * * @param integer $mode Integer representation of data transfer mode [1:Binary|0:Ascii] * Defined constants can also be used [FTP_BINARY|FTP_ASCII] * * @return boolean True if successful * * @since 12.1 */ protected function _mode($mode) { if ($mode == FTP_BINARY) { if (!$this->_putCmd("TYPE I", 200)) { Log::add(Text::sprintf('JLIB_CLIENT_ERROR_JFTP_MODE_BINARY', $this->_response), Log::WARNING, 'jerror'); return false; } } else { if (!$this->_putCmd("TYPE A", 200)) { Log::add(Text::sprintf('JLIB_CLIENT_ERROR_JFTP_MODE_ASCII', $this->_response), Log::WARNING, 'jerror'); return false; } } return true; }
/** * Static method to get an instance of a JTable class if it can be found in * the table include paths. To add include paths for searching for JTable * classes @see JTable::addIncludePath(). * * @param string $type The type (name) of the JTable class to get an instance of. * @param string $prefix An optional prefix for the table class name. * @param array $config An optional array of configuration values for the JTable object. * * @return mixed A JTable object if found or boolean false if one could not be found. * * @link http://docs.joomla.org/JTable/getInstance * @since 11.1 */ public static function getInstance($type, $prefix = 'JTable', $config = array()) { // Sanitize and prepare the table class name. $type = preg_replace('/[^A-Z0-9_\\.-]/i', '', $type); $tableClass = $prefix . ucfirst($type); // Only try to load the class if it doesn't already exist. if (!class_exists($tableClass)) { // Search for the class file in the JTable include paths. $path = Path::find(self::addIncludePath(), strtolower($type) . '.php'); if ($path) { // Import the class file. include_once $path; // If we were unable to load the proper class, raise a warning and return false. if (!class_exists($tableClass)) { Log::add(Text::sprintf('JLIB_DATABASE_ERROR_CLASS_NOT_FOUND_IN_FILE', $tableClass), Log::WARNING, 'jerror'); return false; } } else { // If we were unable to find the class file in the JTable include paths, raise a warning and return false. Log::add(Text::sprintf('JLIB_DATABASE_ERROR_NOT_SUPPORTED_FILE_NOT_FOUND', $type), Log::WARNING, 'jerror'); return false; } } // If a database object was passed in the configuration array use it, otherwise get the global one from JFactory. $db = isset($config['dbo']) ? $config['dbo'] : Factory::getDbo(); // Instantiate a new table class and return it. return new $tableClass($db); }
/** * Apply the patch * * @param array &$lines The udiff array of lines * @param string $src The source file * @param string $dst The destination file * @param string $src_line The beginning of the patch for the source file * @param string $src_size The size of the patch for the source file * @param string $dst_line The beginning of the patch for the destination file * @param string $dst_size The size of the patch for the destination file * * @return void * * @throw RuntimeException */ protected function applyHunk(&$lines, $src, $dst, $src_line, $src_size, $dst_line, $dst_size) { $src_line--; $dst_line--; $line = current($lines); // Source lines (old file) $source = array(); // New lines (new file) $destin = array(); $src_left = $src_size; $dst_left = $dst_size; do { if (!isset($line[0])) { $source[] = ''; $destin[] = ''; $src_left--; $dst_left--; } elseif ($line[0] == '-') { if ($src_left == 0) { throw new RuntimeException(Text::sprintf('JLIB_FILESYSTEM_PATCHER_REMOVE_LINE', key($lines))); } $source[] = substr($line, 1); $src_left--; } elseif ($line[0] == '+') { if ($dst_left == 0) { throw new RuntimeException(Text::sprintf('JLIB_FILESYSTEM_PATCHER_ADD_LINE', key($lines))); } $destin[] = substr($line, 1); $dst_left--; } elseif ($line != '\\ No newline at end of file') { $line = substr($line, 1); $source[] = $line; $destin[] = $line; $src_left--; $dst_left--; } if ($src_left == 0 && $dst_left == 0) { // Now apply the patch, finally! if ($src_size > 0) { $src_lines =& $this->getSource($src); if (!isset($src_lines)) { throw new RuntimeException(Text::sprintf('JLIB_FILESYSTEM_PATCHER_UNEXISING_SOURCE', $src)); } } if ($dst_size > 0) { if ($src_size > 0) { $dst_lines =& $this->getDestination($dst, $src); $src_bottom = $src_line + count($source); for ($l = $src_line; $l < $src_bottom; $l++) { if ($src_lines[$l] != $source[$l - $src_line]) { throw new RuntimeException(Text::sprintf('JLIB_FILESYSTEM_PATCHER_FAILED_VERIFY', $src, $l)); } } array_splice($dst_lines, $dst_line, count($source), $destin); } else { $this->destinations[$dst] = $destin; } } else { $this->removals[] = $src; } next($lines); return; } $line = next($lines); } while ($line !== false); throw new RuntimeException('Unexpected EOF'); }
/** * Validation and filtering * * @return boolean True if satisfactory * * @since 11.1 */ public function check() { // Set user id to null istead of 0, if needed if ($this->id === 0) { $this->id = null; } // Validate user information if (trim($this->name) == '') { $this->setError(Text::_('JLIB_DATABASE_ERROR_PLEASE_ENTER_YOUR_NAME')); return false; } if (trim($this->username) == '') { $this->setError(Text::_('JLIB_DATABASE_ERROR_PLEASE_ENTER_A_USER_NAME')); return false; } if (preg_match("#[<>\"'%;()&]#i", $this->username) || strlen(utf8_decode($this->username)) < 2) { $this->setError(Text::sprintf('JLIB_DATABASE_ERROR_VALID_AZ09', 2)); return false; } if (trim($this->email) == "" || !Helper::isEmailAddress($this->email)) { $this->setError(Text::_('JLIB_DATABASE_ERROR_VALID_MAIL')); return false; } // Set the registration timestamp if (empty($this->registerDate) || $this->registerDate == $this->_db->getNullDate()) { $this->registerDate = Factory::getDate()->toSql(); } // Set the lastvisitDate timestamp if (empty($this->lastvisitDate)) { $this->lastvisitDate = $this->_db->getNullDate(); } // Check for existing username $query = $this->_db->getQuery(true); $query->select($this->_db->quoteName('id')); $query->from($this->_db->quoteName('#__users')); $query->where($this->_db->quoteName('username') . ' = ' . $this->_db->quote($this->username)); $query->where($this->_db->quoteName('id') . ' != ' . (int) $this->id); $this->_db->setQuery($query); $xid = (int) $this->_db->loadResult(); if ($xid && $xid != (int) $this->id) { $this->setError(Text::_('JLIB_DATABASE_ERROR_USERNAME_INUSE')); return false; } // Check for existing email $query->clear(); $query->select($this->_db->quoteName('id')); $query->from($this->_db->quoteName('#__users')); $query->where($this->_db->quoteName('email') . ' = ' . $this->_db->quote($this->email)); $query->where($this->_db->quoteName('id') . ' != ' . (int) $this->id); $this->_db->setQuery($query); $xid = (int) $this->_db->loadResult(); if ($xid && $xid != (int) $this->id) { $this->setError(Text::_('JLIB_DATABASE_ERROR_EMAIL_INUSE')); return false; } // Check for root_user != username $config = Factory::getConfig(); $rootUser = $config->get('root_user'); if (!is_numeric($rootUser)) { $query->clear(); $query->select($this->_db->quoteName('id')); $query->from($this->_db->quoteName('#__users')); $query->where($this->_db->quoteName('username') . ' = ' . $this->_db->quote($rootUser)); $this->_db->setQuery($query); $xid = (int) $this->_db->loadResult(); if ($rootUser == $this->username && (!$xid || $xid && $xid != (int) $this->id) || $xid && $xid == (int) $this->id && $rootUser != $this->username) { $this->setError(Text::_('JLIB_DATABASE_ERROR_USERNAME_CANNOT_CHANGE')); return false; } } return true; }
/** * Finds out if a set of login credentials are valid by asking all observing * objects to run their respective authentication routines. * * @param array $credentials Array holding the user credentials. * @param array $options Array holding user options. * * @return AuthenticationResponse Response object with status variable filled in for last plugin or first successful plugin. * * @see AuthenticationResponse * @since 11.1 */ public function authenticate($credentials, $options = array()) { // Get plugins $plugins = Helper::getPlugin('authentication'); // Create authentication response $response = new AuthenticationResponse(); /* * Loop through the plugins and check of the credentials can be used to authenticate * the user * * Any errors raised in the plugin should be returned via the AuthenticationResponse * and handled appropriately. */ foreach ($plugins as $plugin) { $className = 'plg' . $plugin->type . $plugin->name; if (class_exists($className)) { $plugin = new $className($this, (array) $plugin); } else { // Bail here if the plugin can't be created Log::add(Text::sprintf('JLIB_USER_ERROR_AUTHENTICATION_FAILED_LOAD_PLUGIN', $className), Log::WARNING, 'jerror'); continue; } // Try to authenticate $plugin->onUserAuthenticate($credentials, $options, $response); // If authentication is successful break out of the loop if ($response->status === self::STATUS_SUCCESS) { if (empty($response->type)) { $response->type = isset($plugin->_name) ? $plugin->_name : $plugin->name; } break; } } if (empty($response->username)) { $response->username = $credentials['username']; } if (empty($response->fullname)) { $response->fullname = $credentials['username']; } if (empty($response->password)) { $response->password = $credentials['password']; } return $response; }
/** * Utility function to read the folders in a folder. * * @param string $path The path of the folder to read. * @param string $filter A filter for folder names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $full True to return the full path to the folders. * @param array $exclude Array with names of folders which should not be shown in the result. * @param array $excludefilter Array with regular expressions matching folders which should not be shown in the result. * * @return array Folders in the given folder. * * @since 11.1 */ public static function folders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludefilter = array('^\\..*')) { // Check to make sure the path valid and clean $path = Path::clean($path); // Is the path a folder? if (!is_dir($path)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FOLDER', $path), Log::WARNING, 'jerror'); return false; } // Compute the excludefilter string if (count($excludefilter)) { $excludefilter_string = '/(' . implode('|', $excludefilter) . ')/'; } else { $excludefilter_string = ''; } // Get the folders $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, false); // Sort the folders asort($arr); return array_values($arr); }
/** * Moves an uploaded file to a destination folder * * @param string $src The name of the php (temporary) uploaded file * @param string $dest The path (including filename) to move the uploaded file to * @param boolean $use_streams True to use streams * * @return boolean True on success * * @since 11.1 */ public static function upload($src, $dest, $use_streams = false) { // Ensure that the path is valid and clean $dest = Path::clean($dest); // Create the destination directory if it does not exist $baseDir = dirname($dest); if (!file_exists($baseDir)) { Folder::create($baseDir); } if ($use_streams) { $stream = Factory::getStream(); if (!$stream->upload($src, $dest)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_UPLOAD', $stream->getError()), Log::WARNING, 'jerror'); return false; } return true; } else { $FTPOptions = ClientHelper::getCredentials('ftp'); $ret = false; if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = ClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path for the FTP account $dest = Path::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/'); // Copy the file to the destination directory if (is_uploaded_file($src) && $ftp->store($src, $dest)) { unlink($src); $ret = true; } else { Log::add(Text::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR02'), Log::WARNING, 'jerror'); } } else { if (is_writeable($baseDir) && move_uploaded_file($src, $dest)) { // Short circuit to prevent file permission errors if (Path::setPermissions($dest)) { $ret = true; } else { Log::add(Text::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR01'), Log::WARNING, 'jerror'); } } else { Log::add(Text::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR02'), Log::WARNING, 'jerror'); } } return $ret; } }
/** * Method to load a JUser object by user id number * * @param mixed $id The user id of the user to load * * @return boolean True on success * * @since 11.1 */ public function load($id) { // Create the user table object $table = $this->getTable(); // Load the JUserModel object based on the user id or throw a warning. if (!$table->load($id)) { // Reset to guest user $this->guest = 1; Log::add(Text::sprintf('JLIB_USER_ERROR_UNABLE_TO_LOAD_USER', $id), Log::WARNING, 'jerror'); return false; } /* * Set the user parameters using the default XML file. We might want to * extend this in the future to allow for the ability to have custom * user parameters, but for right now we'll leave it how it is. */ $this->_params->loadString($table->params); // Assuming all is well at this point let's bind the data $this->setProperties($table->getProperties()); // The user is no longer a guest if ($this->id != 0) { $this->guest = 0; } else { $this->guest = 1; } return true; }
/** * Gets PHP options. * * @return array Array of PHP config options * * @since 1.0 */ public function getPhpOptions() { $options = array(); // Check the PHP Version. $option = new \stdClass(); $option->label = Text::_('INSTL_PHP_VERSION') . ' >= 5.3.10'; $option->state = version_compare(PHP_VERSION, '5.3.10', '>='); $option->notice = null; $options[] = $option; // Check for magic quotes gpc. $option = new \stdClass(); $option->label = Text::_('INSTL_MAGIC_QUOTES_GPC'); $option->state = ini_get('magic_quotes_gpc') == false; $option->notice = null; $options[] = $option; // Check for register globals. $option = new \stdClass(); $option->label = Text::_('INSTL_REGISTER_GLOBALS'); $option->state = ini_get('register_globals') == false; $option->notice = null; $options[] = $option; // Check for zlib support. $option = new \stdClass(); $option->label = Text::_('INSTL_ZLIB_COMPRESSION_SUPPORT'); $option->state = extension_loaded('zlib'); $option->notice = null; $options[] = $option; // Check for XML support. $option = new \stdClass(); $option->label = Text::_('INSTL_XML_SUPPORT'); $option->state = extension_loaded('xml'); $option->notice = null; $options[] = $option; // Check for database support. // We are satisfied if there is at least one database driver available. $available = $this->dboDrivers(); $option = new \stdClass(); $option->label = Text::_('INSTL_DATABASE_SUPPORT'); $option->label .= '<br />(' . implode(', ', $available) . ')'; $option->state = count($available); $option->notice = null; $options[] = $option; // Check for mbstring options. if (extension_loaded('mbstring')) { // Check for default MB language. $option = new \stdClass(); $option->label = Text::_('INSTL_MB_LANGUAGE_IS_DEFAULT'); $option->state = strtolower(ini_get('mbstring.language')) == 'neutral'; $option->notice = $option->state ? null : Text::_('INSTL_NOTICEMBLANGNOTDEFAULT'); $options[] = $option; // Check for MB function overload. $option = new \stdClass(); $option->label = Text::_('INSTL_MB_STRING_OVERLOAD_OFF'); $option->state = ini_get('mbstring.func_overload') == 0; $option->notice = $option->state ? null : Text::_('INSTL_NOTICEMBSTRINGOVERLOAD'); $options[] = $option; } // Check for a missing native parse_ini_file implementation $option = new \stdClass(); $option->label = Text::_('INSTL_PARSE_INI_FILE_AVAILABLE'); $option->state = $this->getIniParserAvailability(); $option->notice = null; $options[] = $option; // Check for missing native json_encode / json_decode support $option = new \stdClass(); $option->label = Text::_('INSTL_JSON_SUPPORT_AVAILABLE'); $option->state = function_exists('json_encode') && function_exists('json_decode'); $option->notice = null; $options[] = $option; // Check for configuration file writable. $writable = is_writable(JPATH_CONFIGURATION . '/configuration.php') || !file_exists(JPATH_CONFIGURATION . '/configuration.php') && is_writable(JPATH_ROOT); $option = new \stdClass(); $option->label = Text::sprintf('INSTL_WRITABLE', 'configuration.php'); $option->state = $writable; $option->notice = $option->state ? null : Text::_('INSTL_NOTICEYOUCANTINSTALL'); $options[] = $option; return $options; }
/** * Method to validate a JFormField object based on field data. * * @param SimpleXMLElement $element The XML element object representation of the form field. * @param string $group The optional dot-separated form group path on which to find the field. * @param mixed $value The optional value to use as the default for the field. * @param Registry $input An optional Registry object with the entire data set to validate * against the entire form. * * @return mixed Boolean true if field value is valid, Exception on failure. * * @since 11.1 * @throws InvalidArgumentException * @throws UnexpectedValueException */ protected function validateField(SimpleXMLElement $element, $group = null, $value = null, Registry $input = null) { $valid = true; // Check if the field is required. $required = (string) $element['required'] == 'true' || (string) $element['required'] == 'required'; if ($required) { // If the field is required and the value is empty return an error message. if ($value === '' || $value === null) { if ($element['label']) { $message = Text::_($element['label']); } else { $message = Text::_($element['name']); } $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_REQUIRED', $message); return new RuntimeException($message); } } // Get the field validation rule. if ($type = (string) $element['validate']) { // Load the JFormRule object for the field. $rule = $this->loadRuleType($type); // If the object could not be loaded return an error message. if ($rule === false) { throw new UnexpectedValueException(sprintf('%s::validateField() rule `%s` missing.', get_class($this), $type)); } // Run the field validation rule test. $valid = $rule->test($element, $value, $group, $input, $this); // Check for an error in the validation test. if ($valid instanceof Exception) { return $valid; } } // Check if the field is valid. if ($valid === false) { // Does the field have a defined error message? $message = (string) $element['message']; if ($message) { $message = Text::_($element['message']); return new UnexpectedValueException($message); } else { $message = Text::_($element['label']); $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $message); return new UnexpectedValueException($message); } } return true; }
/** * Method to get the field input markup for Access Control Lists. * Optionally can be associated with a specific component and section. * * TODO: Add access check. * * @return string The field input markup. * * @since 11.1 */ protected function getInput() { Html::_('behavior.tooltip'); // Initialise some field attributes. $section = $this->element['section'] ? (string) $this->element['section'] : ''; $component = $this->element['component'] ? (string) $this->element['component'] : ''; $assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; // Get the actions for the asset. $actions = Access::getActionsFromFile(JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml', "/access/section[@name='" . $section . "']/"); // Iterate over the children and add to the actions. foreach ($this->element->children() as $el) { if ($el->getName() == 'action') { $actions[] = (object) array('name' => (string) $el['name'], 'title' => (string) $el['title'], 'description' => (string) $el['description']); } } // Get the explicit rules for this asset. if ($section == 'component') { // Need to find the asset id by the name of the component. $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName('id')); $query->from($db->quoteName('#__assets')); $query->where($db->quoteName('name') . ' = ' . $db->quote($component)); $db->setQuery($query); $assetId = (int) $db->loadResult(); } else { // Find the asset id of the content. // Note that for global configuration, com_config injects asset_id = 1 into the form. $assetId = $this->form->getValue($assetField); } // Use the compact form for the content rules (deprecated). /* @todo remove code: if (!empty($component) && $section != 'component') { return Html::_('rules.assetFormWidget', $actions, $assetId, $assetId ? null : $component, $this->name, $this->id); } */ // Full width format. // Get the rules for just this asset (non-recursive). $assetRules = Access::getAssetRules($assetId); // Get the available user groups. $groups = $this->getUserGroups(); // Build the form control. $curLevel = 0; // Prepare output $html = array(); $html[] = '<div id="permissions-sliders" class="pane-sliders">'; $html[] = '<p class="rule-desc">' . Text::_('JLIB_RULES_SETTINGS_DESC') . '</p>'; $html[] = '<ul id="rules">'; // Start a row for each user group. foreach ($groups as $group) { $difLevel = $group->level - $curLevel; if ($difLevel > 0) { $html[] = '<li><ul>'; } elseif ($difLevel < 0) { $html[] = str_repeat('</ul></li>', -$difLevel); } $html[] = '<li>'; $html[] = '<div class="panel">'; $html[] = '<h3 class="pane-toggler title"><a href="javascript:void(0);"><span>'; $html[] = str_repeat('<span class="level">|–</span> ', $curLevel = $group->level) . $group->text; $html[] = '</span></a></h3>'; $html[] = '<div class="pane-slider content pane-hide">'; $html[] = '<div class="mypanel">'; $html[] = '<table class="group-rules">'; $html[] = '<thead>'; $html[] = '<tr>'; $html[] = '<th class="actions" id="actions-th' . $group->value . '">'; $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_ACTION') . '</span>'; $html[] = '</th>'; $html[] = '<th class="settings" id="settings-th' . $group->value . '">'; $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_SELECT_SETTING') . '</span>'; $html[] = '</th>'; // The calculated setting is not shown for the root group of global configuration. $canCalculateSettings = $group->parent_id || !empty($component); if ($canCalculateSettings) { $html[] = '<th id="aclactionth' . $group->value . '">'; $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_CALCULATED_SETTING') . '</span>'; $html[] = '</th>'; } $html[] = '</tr>'; $html[] = '</thead>'; $html[] = '<tbody>'; foreach ($actions as $action) { $html[] = '<tr>'; $html[] = '<td headers="actions-th' . $group->value . '">'; $html[] = '<label class="hasTip" for="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="' . htmlspecialchars(Text::_($action->title) . '::' . Text::_($action->description), ENT_COMPAT, 'UTF-8') . '">'; $html[] = Text::_($action->title); $html[] = '</label>'; $html[] = '</td>'; $html[] = '<td headers="settings-th' . $group->value . '">'; $html[] = '<select name="' . $this->name . '[' . $action->name . '][' . $group->value . ']" id="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="' . Text::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', Text::_($action->title), trim($group->text)) . '">'; $inheritedRule = Access::checkGroup($group->value, $action->name, $assetId); // Get the actual setting for the action for this group. $assetRule = $assetRules->allow($action->name, $group->value); // Build the dropdowns for the permissions sliders // The parent group has "Not Set", all children can rightly "Inherit" from that. $html[] = '<option value=""' . ($assetRule === null ? ' selected="selected"' : '') . '>' . Text::_(empty($group->parent_id) && empty($component) ? 'JLIB_RULES_NOT_SET' : 'JLIB_RULES_INHERITED') . '</option>'; $html[] = '<option value="1"' . ($assetRule === true ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_ALLOWED') . '</option>'; $html[] = '<option value="0"' . ($assetRule === false ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_DENIED') . '</option>'; $html[] = '</select>  '; // If this asset's rule is allowed, but the inherited rule is deny, we have a conflict. if ($assetRule === true && $inheritedRule === false) { $html[] = Text::_('JLIB_RULES_CONFLICT'); } $html[] = '</td>'; // Build the Calculated Settings column. // The inherited settings column is not displayed for the root group in global configuration. if ($canCalculateSettings) { $html[] = '<td headers="aclactionth' . $group->value . '">'; // This is where we show the current effective settings considering currrent group, path and cascade. // Check whether this is a component or global. Change the text slightly. if (Access::checkGroup($group->value, 'core.admin') !== true) { if ($inheritedRule === null) { $html[] = '<span class="icon-16-unset">' . Text::_('JLIB_RULES_NOT_ALLOWED') . '</span>'; } elseif ($inheritedRule === true) { $html[] = '<span class="icon-16-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</span>'; } elseif ($inheritedRule === false) { if ($assetRule === false) { $html[] = '<span class="icon-16-denied">' . Text::_('JLIB_RULES_NOT_ALLOWED') . '</span>'; } else { $html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . Text::_('JLIB_RULES_NOT_ALLOWED_LOCKED') . '</span></span>'; } } } elseif (!empty($component)) { $html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . Text::_('JLIB_RULES_ALLOWED_ADMIN') . '</span></span>'; } else { // Special handling for groups that have global admin because they can't be denied. // The admin rights can be changed. if ($action->name === 'core.admin') { $html[] = '<span class="icon-16-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</span>'; } elseif ($inheritedRule === false) { // Other actions cannot be changed. $html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . Text::_('JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT') . '</span></span>'; } else { $html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . Text::_('JLIB_RULES_ALLOWED_ADMIN') . '</span></span>'; } } $html[] = '</td>'; } $html[] = '</tr>'; } $html[] = '</tbody>'; $html[] = '</table></div>'; $html[] = '</div></div>'; $html[] = '</li>'; } $html[] = str_repeat('</ul></li>', $curLevel); $html[] = '</ul><div class="rule-notes">'; if ($section == 'component' || $section == null) { $html[] = Text::_('JLIB_RULES_SETTING_NOTES'); } else { $html[] = Text::_('JLIB_RULES_SETTING_NOTES_ITEM'); } $html[] = '</div></div>'; // Get the JInput object $input = Factory::getApplication()->input; $js = "window.addEvent('domready', function(){ new Fx.Accordion(\$\$('div#permissions-sliders.pane-sliders .panel h3.pane-toggler')," . "\$\$('div#permissions-sliders.pane-sliders .panel div.pane-slider'), {onActive: function(toggler, i) {toggler.addClass('pane-toggler-down');" . "toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_permissions-sliders" . $component . "',\$\$('div#permissions-sliders.pane-sliders .panel h3').indexOf(toggler));}," . "onBackground: function(toggler, i) {toggler.addClass('pane-toggler');toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');" . "i.removeClass('pane-down');}, duration: 300, display: " . $input->cookie->get('jpanesliders_permissions-sliders' . $component, 0, 'integer') . ", show: " . $input->cookie->get('jpanesliders_permissions-sliders' . $component, 0, 'integer') . ", alwaysHide:true, opacity: false}); });"; Factory::getDocument()->addScriptDeclaration($js); return implode("\n", $html); }
/** * Execute the SQL statement. * * @return mixed A database cursor resource on success, boolean false on failure. * * @since 12.1 * @throws RuntimeException * @throws Exception */ public function execute() { $this->connect(); if (!is_resource($this->connection)) { Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'database'); throw new RuntimeException($this->errorMsg, $this->errorNum); } // Take a local copy so that we don't modify the original query and cause issues later $sql = $this->replacePrefix((string) $this->sql); if ($this->limit > 0 || $this->offset > 0) { $sql = $this->limit($sql, $this->limit, $this->offset); } // Increment the query counter. $this->count++; // If debugging is enabled then let's log the query. if ($this->debug) { // Add the query to the object queue. $this->log[] = $sql; Log::add($sql, Log::DEBUG, 'databasequery'); } // Reset the error values. $this->errorNum = 0; $this->errorMsg = ''; // SQLSrv_num_rows requires a static or keyset cursor. if (strncmp(ltrim(strtoupper($sql)), 'SELECT', strlen('SELECT')) == 0) { $array = array('Scrollable' => SQLSRV_CURSOR_KEYSET); } else { $array = array(); } // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost. $this->cursor = @sqlsrv_query($this->connection, $sql, array(), $array); // If an error occurred handle it. if (!$this->cursor) { // Check if the server was disconnected. if (!$this->connected()) { try { // Attempt to reconnect. $this->connection = null; $this->connect(); } catch (RuntimeException $e) { // Get the error number and message. $errors = sqlsrv_errors(); $this->errorNum = $errors[0]['SQLSTATE']; $this->errorMsg = $errors[0]['message'] . 'SQL=' . $sql; // Throw the normal query exception. Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'databasequery'); throw new RuntimeException($this->errorMsg, $this->errorNum); } // Since we were able to reconnect, run the query again. return $this->execute(); } else { // Get the error number and message. $errors = sqlsrv_errors(); $this->errorNum = $errors[0]['SQLSTATE']; $this->errorMsg = $errors[0]['message'] . 'SQL=' . $sql; // Throw the normal query exception. Log::add(Text::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), Log::ERROR, 'databasequery'); throw new RuntimeException($this->errorMsg, $this->errorNum); } } return $this->cursor; }
/** * Create and return the pagination result set counter string, e.g. Results 1-10 of 42 * * @return string Pagination result set counter string. * * @since 11.1 */ public function getResultsCounter() { $html = null; $fromResult = $this->limitstart + 1; // If the limit is reached before the end of the list. if ($this->limitstart + $this->limit < $this->total) { $toResult = $this->limitstart + $this->limit; } else { $toResult = $this->total; } // If there are results found. if ($this->total > 0) { $msg = Text::sprintf('JLIB_HTML_RESULTS_OF', $fromResult, $toResult, $this->total); $html .= "\n" . $msg; } else { $html .= "\n" . Text::_('JLIB_HTML_NO_RECORDS_FOUND'); } return $html; }
/** * Returns a published state on a grid * * @param integer $value The state value. * @param integer $i The row index * @param string|array $prefix An optional task prefix or an array of options * @param boolean $enabled An optional setting for access control on the action. * @param string $checkbox An optional prefix for checkboxes. * @param string $publish_up An optional start publishing date. * @param string $publish_down An optional finish publishing date. * * @return string The Html code * * @see JHtmlJGrid::state * @since 11.1 */ public static function published($value, $i, $prefix = '', $enabled = true, $checkbox = 'cb', $publish_up = null, $publish_down = null) { if (is_array($prefix)) { $options = $prefix; $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; } $states = array(1 => array('unpublish', 'JPUBLISHED', 'JLIB_HTML_UNPUBLISH_ITEM', 'JPUBLISHED', false, 'publish', 'publish'), 0 => array('publish', 'JUNPUBLISHED', 'JLIB_HTML_PUBLISH_ITEM', 'JUNPUBLISHED', false, 'unpublish', 'unpublish'), 2 => array('unpublish', 'JARCHIVED', 'JLIB_HTML_UNPUBLISH_ITEM', 'JARCHIVED', false, 'archive', 'archive'), -2 => array('publish', 'JTRASHED', 'JLIB_HTML_PUBLISH_ITEM', 'JTRASHED', false, 'trash', 'trash')); // Special state for dates if ($publish_up || $publish_down) { $nullDate = Factory::getDBO()->getNullDate(); $nowDate = Factory::getDate()->toUnix(); $tz = new DateTimeZone(Factory::getUser()->getParam('timezone', Factory::getConfig()->get('offset'))); $publish_up = $publish_up != $nullDate ? Factory::getDate($publish_up, 'UTC')->setTimeZone($tz) : false; $publish_down = $publish_down != $nullDate ? Factory::getDate($publish_down, 'UTC')->setTimeZone($tz) : false; // Create tip text, only we have publish up or down settings $tips = array(); if ($publish_up) { $tips[] = Text::sprintf('JLIB_HTML_PUBLISHED_START', $publish_up->format(Date::$format, true)); } if ($publish_down) { $tips[] = Text::sprintf('JLIB_HTML_PUBLISHED_FINISHED', $publish_down->format(Date::$format, true)); } $tip = empty($tips) ? false : implode('<br/>', $tips); // Add tips and special titles foreach ($states as $key => $state) { // Create special titles for published items if ($key == 1) { $states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_ITEM'; if ($publish_up > $nullDate && $nowDate < $publish_up->toUnix()) { $states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_PENDING_ITEM'; $states[$key][5] = $states[$key][6] = 'pending'; } if ($publish_down > $nullDate && $nowDate > $publish_down->toUnix()) { $states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_EXPIRED_ITEM'; $states[$key][5] = $states[$key][6] = 'expired'; } } // Add tips to titles if ($tip) { $states[$key][1] = Text::_($states[$key][1]); $states[$key][2] = Text::_($states[$key][2]) . '::' . $tip; $states[$key][3] = Text::_($states[$key][3]) . '::' . $tip; $states[$key][4] = true; } } return self::state($states, $value, $i, array('prefix' => $prefix, 'translate' => !$tip), $enabled, true, $checkbox); } return self::state($states, $value, $i, $prefix, $enabled, true, $checkbox); }