예제 #1
0
 /**
  * Run the controller and parse the password template
  *
  * @return Response
  */
 public function run()
 {
     /** @var BackendTemplate|object $objTemplate */
     $objTemplate = new \BackendTemplate('be_password');
     if (\Input::post('FORM_SUBMIT') == 'tl_password') {
         $pw = \Input::postUnsafeRaw('password');
         $cnf = \Input::postUnsafeRaw('confirm');
         // The passwords do not match
         if ($pw != $cnf) {
             \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']);
         } elseif (Utf8::strlen($pw) < \Config::get('minPasswordLength')) {
             \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength')));
         } elseif ($pw == $this->User->username) {
             \Message::addError($GLOBALS['TL_LANG']['ERR']['passwordName']);
         } else {
             // Make sure the password has been changed
             if (\Encryption::verify($pw, $this->User->password)) {
                 \Message::addError($GLOBALS['TL_LANG']['MSC']['pw_change']);
             } else {
                 $this->loadDataContainer('tl_user');
                 // Trigger the save_callback
                 if (is_array($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'])) {
                     foreach ($GLOBALS['TL_DCA']['tl_user']['fields']['password']['save_callback'] as $callback) {
                         if (is_array($callback)) {
                             $this->import($callback[0]);
                             $pw = $this->{$callback[0]}->{$callback[1]}($pw);
                         } elseif (is_callable($callback)) {
                             $pw = $callback($pw);
                         }
                     }
                 }
                 $objUser = \UserModel::findByPk($this->User->id);
                 $objUser->pwChange = '';
                 $objUser->password = \Encryption::hash($pw);
                 $objUser->save();
                 \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']);
                 $this->redirect('contao/main.php');
             }
         }
         $this->reload();
     }
     $objTemplate->theme = \Backend::getTheme();
     $objTemplate->messages = \Message::generate();
     $objTemplate->base = \Environment::get('base');
     $objTemplate->language = $GLOBALS['TL_LANGUAGE'];
     $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['pw_new']);
     $objTemplate->charset = \Config::get('characterSet');
     $objTemplate->action = ampersand(\Environment::get('request'));
     $objTemplate->headline = $GLOBALS['TL_LANG']['MSC']['pw_change'];
     $objTemplate->submitButton = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['continue']);
     $objTemplate->password = $GLOBALS['TL_LANG']['MSC']['password'][0];
     $objTemplate->confirm = $GLOBALS['TL_LANG']['MSC']['confirm'][0];
     return $objTemplate->getResponse();
 }
예제 #2
0
 /**
  * Shorten a HTML string to a given number of characters
  *
  * The function preserves words, so the result might be a bit shorter or
  * longer than the number of characters given. It preserves allowed tags.
  *
  * @param string  $strString        The string to shorten
  * @param integer $intNumberOfChars The target number of characters
  *
  * @return string The shortened HTML string
  */
 public static function substrHtml($strString, $intNumberOfChars)
 {
     $strReturn = '';
     $intCharCount = 0;
     $arrOpenTags = array();
     $arrTagBuffer = array();
     $arrEmptyTags = array('area', 'base', 'br', 'col', 'hr', 'img', 'input', 'frame', 'link', 'meta', 'param');
     $strString = preg_replace('/[\\t\\n\\r]+/', ' ', $strString);
     $strString = strip_tags($strString, \Config::get('allowedTags'));
     $strString = preg_replace('/ +/', ' ', $strString);
     // Seperate tags and text
     $arrChunks = preg_split('/(<[^>]+>)/', $strString, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
     for ($i = 0, $c = count($arrChunks); $i < $c; $i++) {
         // Buffer tags to include them later
         if (preg_match('/<([^>]+)>/', $arrChunks[$i])) {
             $arrTagBuffer[] = $arrChunks[$i];
             continue;
         }
         $buffer = $arrChunks[$i];
         // Get the substring of the current text
         if (($arrChunks[$i] = static::substr($arrChunks[$i], $intNumberOfChars - $intCharCount, false)) == false) {
             break;
         }
         $blnModified = $buffer !== $arrChunks[$i];
         $intCharCount += Utf8::strlen(static::decodeEntities($arrChunks[$i]));
         if ($intCharCount <= $intNumberOfChars) {
             foreach ($arrTagBuffer as $strTag) {
                 $strTagName = strtolower(trim($strTag));
                 // Extract the tag name (see #5669)
                 if (($pos = strpos($strTagName, ' ')) !== false) {
                     $strTagName = substr($strTagName, 1, $pos - 1);
                 } else {
                     $strTagName = substr($strTagName, 1, -1);
                 }
                 // Skip empty tags
                 if (in_array($strTagName, $arrEmptyTags)) {
                     continue;
                 }
                 // Store opening tags in the open_tags array
                 if (strncmp($strTagName, '/', 1) !== 0) {
                     if (!empty($arrChunks[$i]) || $i < $c) {
                         $arrOpenTags[] = $strTagName;
                     }
                     continue;
                 }
                 // Closing tags will be removed from the "open tags" array
                 if (!empty($arrChunks[$i]) || $i < $c) {
                     $arrOpenTags = array_values($arrOpenTags);
                     for ($j = count($arrOpenTags) - 1; $j >= 0; $j--) {
                         if ($strTagName == '/' . $arrOpenTags[$j]) {
                             unset($arrOpenTags[$j]);
                             break;
                         }
                     }
                 }
             }
             // If the current chunk contains text, add tags and text to the return string
             if (strlen($arrChunks[$i]) || $i < $c) {
                 $strReturn .= implode('', $arrTagBuffer) . $arrChunks[$i];
             }
             // Stop after the first shortened chunk (see #7311)
             if ($blnModified) {
                 break;
             }
             $arrTagBuffer = array();
             continue;
         }
         break;
     }
     // Close all remaining open tags
     krsort($arrOpenTags);
     foreach ($arrOpenTags as $strTag) {
         $strReturn .= '</' . $strTag . '>';
     }
     return trim($strReturn);
 }
예제 #3
0
 /**
  * @covers Patchwork\Utf8::str_shuffle
  */
 function testStr_shuffle()
 {
     $c = "déjà 한국어";
     $c .= n::normalize($c, n::NFD);
     $this->assertTrue($c != ($d = u::str_shuffle($c)) || $c != ($d = u::str_shuffle($c)));
     $this->assertSame(strlen($c), strlen($d));
     $this->assertSame(u::strlen($c), u::strlen($d));
     $this->assertSame('', u::trim($d, $c));
 }
예제 #4
0
 /**
  * Recursively generate the tree and return it as HTML string
  *
  * @param string  $table
  * @param integer $id
  * @param array   $arrPrevNext
  * @param boolean $blnHasSorting
  * @param integer $intMargin
  * @param array   $arrClipboard
  * @param boolean $blnCircularReference
  * @param boolean $protectedPage
  * @param boolean $blnNoRecursion
  * @param array   $arrFound
  *
  * @return string
  */
 protected function generateTree($table, $id, $arrPrevNext, $blnHasSorting, $intMargin = 0, $arrClipboard = null, $blnCircularReference = false, $protectedPage = false, $blnNoRecursion = false, $arrFound = array())
 {
     static $session;
     /** @var AttributeBagInterface $objSessionBag */
     $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend');
     $session = $objSessionBag->all();
     $node = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6 ? $this->strTable . '_' . $table . '_tree' : $this->strTable . '_tree';
     // Toggle nodes
     if (\Input::get('ptg')) {
         $session[$node][\Input::get('ptg')] = isset($session[$node][\Input::get('ptg')]) && $session[$node][\Input::get('ptg')] == 1 ? 0 : 1;
         $objSessionBag->replace($session);
         $this->redirect(preg_replace('/(&(amp;)?|\\?)ptg=[^& ]*/i', '', \Environment::get('request')));
     }
     $objRow = $this->Database->prepare("SELECT * FROM " . $table . " WHERE id=?")->limit(1)->execute($id);
     // Return if there is no result
     if ($objRow->numRows < 1) {
         $objSessionBag->replace($session);
         return '';
     }
     $return = '';
     $intSpacing = 20;
     $childs = array();
     // Add the ID to the list of current IDs
     if ($this->strTable == $table) {
         $this->current[] = $objRow->id;
     }
     // Check whether there are child records
     if (!$blnNoRecursion) {
         if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 5 || $this->strTable != $table) {
             $objChilds = $this->Database->prepare("SELECT id FROM " . $table . " WHERE pid=?" . (!empty($arrFound) ? " AND id IN(" . implode(',', array_map('intval', $arrFound)) . ")" : '') . ($blnHasSorting ? " ORDER BY sorting" : ''))->execute($id);
             if ($objChilds->numRows) {
                 $childs = $objChilds->fetchEach('id');
             }
         }
     }
     $blnProtected = false;
     // Check whether the page is protected
     if ($table == 'tl_page') {
         $blnProtected = $objRow->protected || $protectedPage ? true : false;
     }
     $session[$node][$id] = is_int($session[$node][$id]) ? $session[$node][$id] : 0;
     $mouseover = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 5 || $table == $this->strTable ? ' toggle_select hover-div"' : '"';
     $return .= "\n  " . '<li class="' . ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 5 && $objRow->type == 'root' || $table != $this->strTable ? 'tl_folder' : 'tl_file') . ' click2edit' . $mouseover . '><div class="tl_left" style="padding-left:' . ($intMargin + $intSpacing) . 'px">';
     // Calculate label and add a toggle button
     $args = array();
     $folderAttribute = 'style="margin-left:20px"';
     $showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields'];
     $level = $intMargin / $intSpacing + 1;
     if (!empty($childs)) {
         $folderAttribute = '';
         $img = !empty($arrFound) || $session[$node][$id] == 1 ? 'folMinus.gif' : 'folPlus.gif';
         $alt = !empty($arrFound) || $session[$node][$id] == 1 ? $GLOBALS['TL_LANG']['MSC']['collapseNode'] : $GLOBALS['TL_LANG']['MSC']['expandNode'];
         $return .= '<a href="' . $this->addToUrl('ptg=' . $id) . '" title="' . specialchars($alt) . '" onclick="Backend.getScrollOffset();return AjaxRequest.toggleStructure(this,\'' . $node . '_' . $id . '\',' . $level . ',' . $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] . ')">' . \Image::getHtml($img, '', 'style="margin-right:2px"') . '</a>';
     }
     foreach ($showFields as $k => $v) {
         // Decrypt the value
         if ($GLOBALS['TL_DCA'][$table]['fields'][$v]['eval']['encrypt']) {
             $objRow->{$v} = \Encryption::decrypt(deserialize($objRow->{$v}));
         }
         if (strpos($v, ':') !== false) {
             list($strKey, $strTable) = explode(':', $v);
             list($strTable, $strField) = explode('.', $strTable);
             $objRef = $this->Database->prepare("SELECT " . $strField . " FROM " . $strTable . " WHERE id=?")->limit(1)->execute($objRow->{$strKey});
             $args[$k] = $objRef->numRows ? $objRef->{$strField} : '';
         } elseif (in_array($GLOBALS['TL_DCA'][$table]['fields'][$v]['flag'], array(5, 6, 7, 8, 9, 10))) {
             $args[$k] = \Date::parse(\Config::get('datimFormat'), $objRow->{$v});
         } elseif ($GLOBALS['TL_DCA'][$table]['fields'][$v]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$table]['fields'][$v]['eval']['multiple']) {
             $args[$k] = $objRow->{$v} != '' ? isset($GLOBALS['TL_DCA'][$table]['fields'][$v]['label'][0]) ? $GLOBALS['TL_DCA'][$table]['fields'][$v]['label'][0] : $v : '';
         } else {
             $args[$k] = $GLOBALS['TL_DCA'][$table]['fields'][$v]['reference'][$objRow->{$v}] ?: $objRow->{$v};
         }
     }
     $label = vsprintf(strlen($GLOBALS['TL_DCA'][$table]['list']['label']['format']) ? $GLOBALS['TL_DCA'][$table]['list']['label']['format'] : '%s', $args);
     // Shorten the label if it is too long
     if ($GLOBALS['TL_DCA'][$table]['list']['label']['maxCharacters'] > 0 && $GLOBALS['TL_DCA'][$table]['list']['label']['maxCharacters'] < Utf8::strlen(strip_tags($label))) {
         $label = trim(\StringUtil::substrHtml($label, $GLOBALS['TL_DCA'][$table]['list']['label']['maxCharacters'])) . ' …';
     }
     $label = preg_replace('/\\(\\) ?|\\[\\] ?|\\{\\} ?|<> ?/', '', $label);
     // Call the label_callback ($row, $label, $this)
     if (is_array($GLOBALS['TL_DCA'][$table]['list']['label']['label_callback'])) {
         $strClass = $GLOBALS['TL_DCA'][$table]['list']['label']['label_callback'][0];
         $strMethod = $GLOBALS['TL_DCA'][$table]['list']['label']['label_callback'][1];
         $this->import($strClass);
         $return .= $this->{$strClass}->{$strMethod}($objRow->row(), $label, $this, $folderAttribute, false, $blnProtected);
     } elseif (is_callable($GLOBALS['TL_DCA'][$table]['list']['label']['label_callback'])) {
         $return .= $GLOBALS['TL_DCA'][$table]['list']['label']['label_callback']($objRow->row(), $label, $this, $folderAttribute, false, $blnProtected);
     } else {
         $return .= \Image::getHtml('iconPLAIN.gif', '') . ' ' . $label;
     }
     $return .= '</div> <div class="tl_right">';
     $previous = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6 ? $arrPrevNext['pp'] : $arrPrevNext['p'];
     $next = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 6 ? $arrPrevNext['nn'] : $arrPrevNext['n'];
     $_buttons = '';
     // Regular buttons ($row, $table, $root, $blnCircularReference, $childs, $previous, $next)
     if ($this->strTable == $table) {
         $_buttons .= \Input::get('act') == 'select' ? '<input type="checkbox" name="IDS[]" id="ids_' . $id . '" class="tl_tree_checkbox" value="' . $id . '">' : $this->generateButtons($objRow->row(), $table, $this->root, $blnCircularReference, $childs, $previous, $next);
     }
     // Paste buttons
     if ($arrClipboard !== false && \Input::get('act') != 'select') {
         $_buttons .= ' ';
         // Call paste_button_callback(&$dc, $row, $table, $blnCircularReference, $arrClipboard, $childs, $previous, $next)
         if (is_array($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['paste_button_callback'])) {
             $strClass = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['paste_button_callback'][0];
             $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['paste_button_callback'][1];
             $this->import($strClass);
             $_buttons .= $this->{$strClass}->{$strMethod}($this, $objRow->row(), $table, $blnCircularReference, $arrClipboard, $childs, $previous, $next);
         } elseif (is_callable($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['paste_button_callback'])) {
             $_buttons .= $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['paste_button_callback']($this, $objRow->row(), $table, $blnCircularReference, $arrClipboard, $childs, $previous, $next);
         } else {
             $imagePasteAfter = \Image::getHtml('pasteafter.gif', sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][1], $id));
             $imagePasteInto = \Image::getHtml('pasteinto.gif', sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1], $id));
             // Regular tree (on cut: disable buttons of the page all its childs to avoid circular references)
             if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 5) {
                 $_buttons .= $arrClipboard['mode'] == 'cut' && ($blnCircularReference || $arrClipboard['id'] == $id) || $arrClipboard['mode'] == 'cutAll' && ($blnCircularReference || in_array($id, $arrClipboard['id'])) || !empty($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['root']) && !$GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['rootPaste'] && in_array($id, $this->root) ? \Image::getHtml('pasteafter_.gif') . ' ' : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=1&amp;pid=' . $id . (!is_array($arrClipboard['id']) ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][1], $id)) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a> ';
                 $_buttons .= $arrClipboard['mode'] == 'paste' && ($blnCircularReference || $arrClipboard['id'] == $id) || $arrClipboard['mode'] == 'cutAll' && ($blnCircularReference || in_array($id, $arrClipboard['id'])) ? \Image::getHtml('pasteinto_.gif') . ' ' : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=2&amp;pid=' . $id . (!is_array($arrClipboard['id']) ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1], $id)) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a> ';
             } else {
                 $_buttons .= $this->strTable == $table ? $arrClipboard['mode'] == 'cut' && ($blnCircularReference || $arrClipboard['id'] == $id) || $arrClipboard['mode'] == 'cutAll' && ($blnCircularReference || in_array($id, $arrClipboard['id'])) ? \Image::getHtml('pasteafter_.gif') : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=1&amp;pid=' . $id . (!is_array($arrClipboard['id']) ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteafter'][1], $id)) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a> ' : '';
                 $_buttons .= $this->strTable != $table ? '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=2&amp;pid=' . $id . (!is_array($arrClipboard['id']) ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . specialchars(sprintf($GLOBALS['TL_LANG'][$this->strTable]['pasteinto'][1], $id)) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a> ' : '';
             }
         }
     }
     $return .= ($_buttons ?: '&nbsp;') . '</div><div style="clear:both"></div></li>';
     // Add the records of the table itself
     if ($table != $this->strTable) {
         $objChilds = $this->Database->prepare("SELECT id FROM " . $this->strTable . " WHERE pid=?" . ($blnHasSorting ? " ORDER BY sorting" : ''))->execute($id);
         if ($objChilds->numRows) {
             $ids = $objChilds->fetchEach('id');
             for ($j = 0, $c = count($ids); $j < $c; $j++) {
                 $return .= $this->generateTree($this->strTable, $ids[$j], array('pp' => $ids[$j - 1], 'nn' => $ids[$j + 1]), $blnHasSorting, $intMargin + $intSpacing + 20, $arrClipboard, false, $j < count($ids) - 1 || !empty($childs), $blnNoRecursion, $arrFound);
             }
         }
     }
     // Begin a new submenu
     if (!$blnNoRecursion) {
         if (!empty($arrFound) || !empty($childs) && $session[$node][$id] == 1) {
             $return .= '<li class="parent" id="' . $node . '_' . $id . '"><ul class="level_' . $level . '">';
         }
         // Add the records of the parent table
         if (!empty($arrFound) || $session[$node][$id] == 1) {
             if (is_array($childs)) {
                 for ($k = 0, $c = count($childs); $k < $c; $k++) {
                     $return .= $this->generateTree($table, $childs[$k], array('p' => $childs[$k - 1], 'n' => $childs[$k + 1]), $blnHasSorting, $intMargin + $intSpacing, $arrClipboard, $GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 5 && $childs[$k] == $arrClipboard['id'] || $blnCircularReference ? true : false, $blnProtected || $protectedPage, $blnNoRecursion, $arrFound);
                 }
             }
         }
         // Close the submenu
         if (!empty($arrFound) || !empty($childs) && $session[$node][$id] == 1) {
             $return .= '</ul></li>';
         }
     }
     $objSessionBag->replace($session);
     return $return;
 }
/**
 * Returns length of the input string.
 * @param string $string				The string which length is to be calculated.
 * @param string $encoding (optional)	The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
 * @return int							Returns the number of characters within the string. A multi-byte character is counted as 1.
 * This function is aimed at replacing the functions strlen() and mb_strlen() for human-language strings.
 * @link http://php.net/manual/en/function.strlen
 * @link http://php.net/manual/en/function.mb-strlen
 * Note: When you use strlen() to test for an empty string, you needn't change it to api_strlen().
 * For example, in lines like the following:
 * if (strlen($string) > 0)
 * if (strlen($string) != 0)
 * there is no need the original function strlen() to be changed, it works correctly and faster for these cases.
 */
function api_strlen($string, $encoding = null)
{
    return Utf8::strlen($string);
}
예제 #6
0
 /**
  * Recursively validate an input variable
  *
  * @param mixed $varInput The user input
  *
  * @return mixed The original or modified user input
  */
 protected function validator($varInput)
 {
     if (is_array($varInput)) {
         foreach ($varInput as $k => $v) {
             $varInput[$k] = $this->validator($v);
         }
         return $varInput;
     }
     if (!$this->doNotTrim) {
         $varInput = trim($varInput);
     }
     if ($varInput == '') {
         if (!$this->mandatory) {
             return '';
         } else {
             if ($this->strLabel == '') {
                 $this->addError($GLOBALS['TL_LANG']['ERR']['mdtryNoLabel']);
             } else {
                 $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['mandatory'], $this->strLabel));
             }
         }
     }
     if ($this->minlength && $varInput != '' && Utf8::strlen($varInput) < $this->minlength) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['minlength'], $this->strLabel, $this->minlength));
     }
     if ($this->maxlength && $varInput != '' && Utf8::strlen($varInput) > $this->maxlength) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['maxlength'], $this->strLabel, $this->maxlength));
     }
     if ($this->minval && is_numeric($varInput) && $varInput < $this->minval) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['minval'], $this->strLabel, $this->minval));
     }
     if ($this->maxval && is_numeric($varInput) && $varInput > $this->maxval) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['maxval'], $this->strLabel, $this->maxval));
     }
     if ($this->rgxp != '') {
         switch ($this->rgxp) {
             // Special validation rule for style sheets
             case strncmp($this->rgxp, 'digit_', 6) === 0:
                 $textual = explode('_', $this->rgxp);
                 array_shift($textual);
                 if (in_array($varInput, $textual) || strncmp($varInput, '$', 1) === 0) {
                     break;
                 }
                 // DO NOT ADD A break; STATEMENT HERE
                 // Numeric characters (including full stop [.] and minus [-])
             // DO NOT ADD A break; STATEMENT HERE
             // Numeric characters (including full stop [.] and minus [-])
             case 'digit':
                 // Support decimal commas and convert them automatically (see #3488)
                 if (substr_count($varInput, ',') == 1 && strpos($varInput, '.') === false) {
                     $varInput = str_replace(',', '.', $varInput);
                 }
                 if (!\Validator::isNumeric($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['digit'], $this->strLabel));
                 }
                 break;
                 // Natural numbers (positive integers)
             // Natural numbers (positive integers)
             case 'natural':
                 if (!\Validator::isNatural($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['natural'], $this->strLabel));
                 }
                 break;
                 // Alphabetic characters (including full stop [.] minus [-] and space [ ])
             // Alphabetic characters (including full stop [.] minus [-] and space [ ])
             case 'alpha':
                 if (!\Validator::isAlphabetic($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alpha'], $this->strLabel));
                 }
                 break;
                 // Alphanumeric characters (including full stop [.] minus [-], underscore [_] and space [ ])
             // Alphanumeric characters (including full stop [.] minus [-], underscore [_] and space [ ])
             case 'alnum':
                 if (!\Validator::isAlphanumeric($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alnum'], $this->strLabel));
                 }
                 break;
                 // Do not allow any characters that are usually encoded by class Input ([#<>()\=])
             // Do not allow any characters that are usually encoded by class Input ([#<>()\=])
             case 'extnd':
                 if (!\Validator::isExtendedAlphanumeric(html_entity_decode($varInput))) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['extnd'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a valid date format
             // Check whether the current value is a valid date format
             case 'date':
                 if (!\Validator::isDate($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['date'], \Date::getInputFormat(\Date::getNumericDateFormat())));
                 } else {
                     // Validate the date (see #5086)
                     try {
                         new \Date($varInput, \Date::getNumericDateFormat());
                     } catch (\OutOfBoundsException $e) {
                         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varInput));
                     }
                 }
                 break;
                 // Check whether the current value is a valid time format
             // Check whether the current value is a valid time format
             case 'time':
                 if (!\Validator::isTime($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['time'], \Date::getInputFormat(\Date::getNumericTimeFormat())));
                 }
                 break;
                 // Check whether the current value is a valid date and time format
             // Check whether the current value is a valid date and time format
             case 'datim':
                 if (!\Validator::isDatim($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['dateTime'], \Date::getInputFormat(\Date::getNumericDatimFormat())));
                 } else {
                     // Validate the date (see #5086)
                     try {
                         new \Date($varInput, \Date::getNumericDatimFormat());
                     } catch (\OutOfBoundsException $e) {
                         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varInput));
                     }
                 }
                 break;
                 // Check whether the current value is a valid friendly name e-mail address
             // Check whether the current value is a valid friendly name e-mail address
             case 'friendly':
                 list($strName, $varInput) = \StringUtil::splitFriendlyEmail($varInput);
                 // no break;
                 // Check whether the current value is a valid e-mail address
             // no break;
             // Check whether the current value is a valid e-mail address
             case 'email':
                 if (!\Validator::isEmail($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['email'], $this->strLabel));
                 }
                 if ($this->rgxp == 'friendly' && !empty($strName)) {
                     $varInput = $strName . ' [' . $varInput . ']';
                 }
                 break;
                 // Check whether the current value is list of valid e-mail addresses
             // Check whether the current value is list of valid e-mail addresses
             case 'emails':
                 $arrEmails = \StringUtil::trimsplit(',', $varInput);
                 foreach ($arrEmails as $strEmail) {
                     $strEmail = \Idna::encodeEmail($strEmail);
                     if (!\Validator::isEmail($strEmail)) {
                         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['emails'], $this->strLabel));
                         break;
                     }
                 }
                 break;
                 // Check whether the current value is a valid URL
             // Check whether the current value is a valid URL
             case 'url':
                 if (!\Validator::isUrl($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['url'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a valid alias
             // Check whether the current value is a valid alias
             case 'alias':
                 if (!\Validator::isAlias($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alias'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a valid folder URL alias
             // Check whether the current value is a valid folder URL alias
             case 'folderalias':
                 if (!\Validator::isFolderAlias($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['folderalias'], $this->strLabel));
                 }
                 break;
                 // Phone numbers (numeric characters, space [ ], plus [+], minus [-], parentheses [()] and slash [/])
             // Phone numbers (numeric characters, space [ ], plus [+], minus [-], parentheses [()] and slash [/])
             case 'phone':
                 if (!\Validator::isPhone(html_entity_decode($varInput))) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['phone'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a percent value
             // Check whether the current value is a percent value
             case 'prcnt':
                 if (!\Validator::isPercent($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['prcnt'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a locale
             // Check whether the current value is a locale
             case 'locale':
                 if (!\Validator::isLocale($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['locale'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a language code
             // Check whether the current value is a language code
             case 'language':
                 if (!\Validator::isLanguage($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['language'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a Google+ ID or vanity name
             // Check whether the current value is a Google+ ID or vanity name
             case 'google+':
                 if (!\Validator::isGooglePlusId($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidGoogleId'], $this->strLabel));
                 }
                 break;
                 // Check whether the current value is a field name
             // Check whether the current value is a field name
             case 'fieldname':
                 if (!\Validator::isFieldName($varInput)) {
                     $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidFieldName'], $this->strLabel));
                 }
                 break;
                 // HOOK: pass unknown tags to callback functions
             // HOOK: pass unknown tags to callback functions
             default:
                 if (isset($GLOBALS['TL_HOOKS']['addCustomRegexp']) && is_array($GLOBALS['TL_HOOKS']['addCustomRegexp'])) {
                     foreach ($GLOBALS['TL_HOOKS']['addCustomRegexp'] as $callback) {
                         $this->import($callback[0]);
                         $break = $this->{$callback[0]}->{$callback[1]}($this->rgxp, $varInput, $this);
                         // Stop the loop if a callback returned true
                         if ($break === true) {
                             break;
                         }
                     }
                 }
                 break;
         }
     }
     if ($this->isHexColor && $varInput != '' && strncmp($varInput, '$', 1) !== 0) {
         $varInput = preg_replace('/[^a-f0-9]+/i', '', $varInput);
     }
     if ($this->nospace && preg_match('/[\\t ]+/', $varInput)) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['noSpace'], $this->strLabel));
     }
     if ($this->spaceToUnderscore) {
         $varInput = preg_replace('/\\s+/', '_', trim($varInput));
     }
     if (is_bool($this->trailingSlash) && $varInput != '') {
         $varInput = preg_replace('/\\/+$/', '', $varInput) . ($this->trailingSlash ? '/' : '');
     }
     return $varInput;
 }
예제 #7
0
 /**
  * Creates an admin user.
  *
  * @return Response|RedirectResponse|null The response object
  */
 private function createAdminUser()
 {
     $installTool = $this->container->get('contao.install_tool');
     if (!$installTool->hasTable('tl_user')) {
         $this->context['hide_admin'] = true;
         return null;
     }
     if ($installTool->hasAdminUser()) {
         $this->context['has_admin'] = true;
         return null;
     }
     $request = $this->container->get('request_stack')->getCurrentRequest();
     if ('tl_admin' !== $request->request->get('FORM_SUBMIT')) {
         return null;
     }
     $username = $request->request->get('username');
     $name = $request->request->get('name');
     $email = $request->request->get('email');
     $password = $request->request->get('password');
     $confirmation = $request->request->get('confirmation');
     $this->context['admin_username_value'] = $username;
     $this->context['admin_name_value'] = $name;
     $this->context['admin_email_value'] = $email;
     // All fields are mandatory
     if ('' === $username || '' === $name || '' === $email || '' === $password) {
         $this->context['admin_error'] = $this->trans('admin_error');
         return null;
     }
     // Do not allow special characters in usernames
     if (preg_match('/[#()\\/<=>]/', $username)) {
         $this->context['admin_username_error'] = $this->trans('admin_error_extnd');
         return null;
     }
     // The username must not contain whitespace characters (see #4006)
     if (false !== strpos($username, ' ')) {
         $this->context['admin_username_error'] = $this->trans('admin_error_no_space');
         return null;
     }
     // Validate the e-mail address (see #6003)
     if ($email !== filter_var($email, FILTER_VALIDATE_EMAIL)) {
         $this->context['admin_email_error'] = $this->trans('admin_error_email');
         return null;
     }
     // The passwords do not match
     if ($password !== $confirmation) {
         $this->context['admin_password_error'] = $this->trans('admin_error_password_match');
         return null;
     }
     $minlength = $installTool->getConfig('minPasswordLength');
     // The password is too short
     if (Utf8::strlen($password) < $minlength) {
         $this->context['admin_password_error'] = sprintf($this->trans('password_too_short'), $minlength);
         return null;
     }
     // Password and username are the same
     if ($password === $username) {
         $this->context['admin_password_error'] = sprintf($this->trans('admin_error_password_user'), $minlength);
         return null;
     }
     $installTool->persistConfig('adminEmail', $email);
     $installTool->persistAdminUser($username, $name, $email, $password, $this->container->getParameter('locale'));
     return $this->getRedirectResponse();
 }
 public function test_empty_str()
 {
     $str = '';
     $this->assertEquals(0, u::strlen($str));
 }
예제 #9
0
/**
 * Determine the number of characters of a string
 *
 * @param string $str
 *
 * @return integer
 *
 * @deprecated Deprecated since Contao 4.0, to be removed in Contao 5.0.
 *             Use Patchwork\Utf8::strlen() instead.
 */
function utf8_strlen($str)
{
    @trigger_error('Using utf8_strlen() has been deprecated and will no longer work in Contao 5.0. Use Patchwork\\Utf8::strlen() instead.', E_USER_DEPRECATED);
    return Utf8::strlen($str);
}
예제 #10
0
파일: String.php 프로젝트: robclancy/string
 public function length()
 {
     return u::strlen($this->string);
 }
 private function passwordValidator($password, $minLength, $username)
 {
     if (Utf8::strlen($password) < $minLength) {
         throw new \RuntimeException('The given password is too short (Minimum ' . $minLength . ' characters)');
     }
     if ($password == $username) {
         throw new \RuntimeException('Username and password must not be the same');
     }
     return $password;
 }
예제 #12
0
 /**
  * Validate input and set value
  *
  * @param mixed $varInput The user input
  *
  * @return mixed The validated user input
  */
 protected function validator($varInput)
 {
     $this->blnSubmitInput = false;
     if (!strlen($varInput) && (strlen($this->varValue) || !$this->mandatory)) {
         return '';
     }
     if (Utf8::strlen($varInput) < \Config::get('minPasswordLength')) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength')));
     }
     if ($varInput != $this->getPost($this->strName . '_confirm')) {
         $this->addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']);
     }
     $varInput = parent::validator($varInput);
     if (!$this->hasErrors()) {
         $this->blnSubmitInput = true;
         return \Encryption::hash($varInput);
     }
     return '';
 }
예제 #13
0
 /**
  * Index a page
  *
  * @param array $arrData The data array
  *
  * @return boolean True if a new record was created
  */
 public static function indexPage($arrData)
 {
     $objDatabase = \Database::getInstance();
     $arrSet['url'] = $arrData['url'];
     $arrSet['title'] = $arrData['title'];
     $arrSet['protected'] = $arrData['protected'];
     $arrSet['filesize'] = $arrData['filesize'];
     $arrSet['groups'] = $arrData['groups'];
     $arrSet['pid'] = $arrData['pid'];
     $arrSet['language'] = $arrData['language'];
     // Get the file size from the raw content
     if (!$arrSet['filesize']) {
         $arrSet['filesize'] = number_format(strlen($arrData['content']) / 1024, 2, '.', '');
     }
     // Replace special characters
     $strContent = str_replace(array("\n", "\r", "\t", '&#160;', '&nbsp;'), ' ', $arrData['content']);
     // Strip script tags
     while (($intStart = strpos($strContent, '<script')) !== false) {
         if (($intEnd = strpos($strContent, '</script>', $intStart)) !== false) {
             $strContent = substr($strContent, 0, $intStart) . substr($strContent, $intEnd + 9);
         } else {
             break;
             // see #5119
         }
     }
     // Strip style tags
     while (($intStart = strpos($strContent, '<style')) !== false) {
         if (($intEnd = strpos($strContent, '</style>', $intStart)) !== false) {
             $strContent = substr($strContent, 0, $intStart) . substr($strContent, $intEnd + 8);
         } else {
             break;
             // see #5119
         }
     }
     // Strip non-indexable areas
     while (($intStart = strpos($strContent, '<!-- indexer::stop -->')) !== false) {
         if (($intEnd = strpos($strContent, '<!-- indexer::continue -->', $intStart)) !== false) {
             $intCurrent = $intStart;
             // Handle nested tags
             while (($intNested = strpos($strContent, '<!-- indexer::stop -->', $intCurrent + 22)) !== false && $intNested < $intEnd) {
                 if (($intNewEnd = strpos($strContent, '<!-- indexer::continue -->', $intEnd + 26)) !== false) {
                     $intEnd = $intNewEnd;
                     $intCurrent = $intNested;
                 } else {
                     break;
                     // see #5119
                 }
             }
             $strContent = substr($strContent, 0, $intStart) . substr($strContent, $intEnd + 26);
         } else {
             break;
             // see #5119
         }
     }
     // HOOK: add custom logic
     if (isset($GLOBALS['TL_HOOKS']['indexPage']) && is_array($GLOBALS['TL_HOOKS']['indexPage'])) {
         foreach ($GLOBALS['TL_HOOKS']['indexPage'] as $callback) {
             \System::importStatic($callback[0])->{$callback[1]}($strContent, $arrData, $arrSet);
         }
     }
     // Free the memory
     unset($arrData['content']);
     // Calculate the checksum (see #4179)
     $arrSet['checksum'] = md5(preg_replace('/ +/', ' ', strip_tags($strContent)));
     // Return if the page is indexed and up to date
     $objIndex = $objDatabase->prepare("SELECT id, checksum FROM tl_search WHERE url=? AND pid=?")->limit(1)->execute($arrSet['url'], $arrSet['pid']);
     if ($objIndex->numRows && $objIndex->checksum == $arrSet['checksum']) {
         return false;
     }
     $arrMatches = array();
     preg_match('/<\\/head>/', $strContent, $arrMatches, PREG_OFFSET_CAPTURE);
     $intOffset = strlen($arrMatches[0][0]) + $arrMatches[0][1];
     // Split page in head and body section
     $strHead = substr($strContent, 0, $intOffset);
     $strBody = substr($strContent, $intOffset);
     unset($strContent);
     $tags = array();
     // Get description
     if (preg_match('/<meta[^>]+name="description"[^>]+content="([^"]*)"[^>]*>/i', $strHead, $tags)) {
         $arrData['description'] = trim(preg_replace('/ +/', ' ', \StringUtil::decodeEntities($tags[1])));
     }
     // Get keywords
     if (preg_match('/<meta[^>]+name="keywords"[^>]+content="([^"]*)"[^>]*>/i', $strHead, $tags)) {
         $arrData['keywords'] = trim(preg_replace('/ +/', ' ', \StringUtil::decodeEntities($tags[1])));
     }
     // Read title and alt attributes
     if (preg_match_all('/<* (title|alt)="([^"]*)"[^>]*>/i', $strBody, $tags)) {
         $arrData['keywords'] .= ' ' . implode(', ', array_unique($tags[2]));
     }
     // Add a whitespace character before line-breaks and between consecutive tags (see #5363)
     $strBody = str_ireplace(array('<br', '><'), array(' <br', '> <'), $strBody);
     $strBody = strip_tags($strBody);
     // Put everything together
     $arrSet['text'] = $arrData['title'] . ' ' . $arrData['description'] . ' ' . $strBody . ' ' . $arrData['keywords'];
     $arrSet['text'] = trim(preg_replace('/ +/', ' ', \StringUtil::decodeEntities($arrSet['text'])));
     $arrSet['tstamp'] = time();
     // Update an existing old entry
     if ($objIndex->numRows) {
         $objDatabase->prepare("UPDATE tl_search %s WHERE id=?")->set($arrSet)->execute($objIndex->id);
         $intInsertId = $objIndex->id;
     } else {
         // Check for a duplicate record with the same checksum
         $objDuplicates = $objDatabase->prepare("SELECT id, url FROM tl_search WHERE pid=? AND checksum=?")->limit(1)->execute($arrSet['pid'], $arrSet['checksum']);
         // Keep the existing record
         if ($objDuplicates->numRows) {
             // Update the URL if the new URL is shorter or the current URL is not canonical
             if (substr_count($arrSet['url'], '/') < substr_count($objDuplicates->url, '/') || strncmp($arrSet['url'] . '?', $objDuplicates->url, Utf8::strlen($arrSet['url']) + 1) === 0) {
                 $objDatabase->prepare("UPDATE tl_search SET url=? WHERE id=?")->execute($arrSet['url'], $objDuplicates->id);
             }
             return false;
         } else {
             $objInsertStmt = $objDatabase->prepare("INSERT INTO tl_search %s")->set($arrSet)->execute();
             $intInsertId = $objInsertStmt->insertId;
         }
     }
     // Remove quotes
     $strText = str_replace(array('´', '`'), "'", $arrSet['text']);
     unset($arrSet);
     // Remove special characters
     $strText = preg_replace(array('/- /', '/ -/', "/' /", "/ '/", '/\\. /', '/\\.$/', '/: /', '/:$/', '/, /', '/,$/', '/[^\\w\'.:,+-]/u'), ' ', $strText);
     // Split words
     $arrWords = preg_split('/ +/', Utf8::strtolower($strText));
     $arrIndex = array();
     // Index words
     foreach ($arrWords as $strWord) {
         // Strip a leading plus (see #4497)
         if (strncmp($strWord, '+', 1) === 0) {
             $strWord = substr($strWord, 1);
         }
         $strWord = trim($strWord);
         if (!strlen($strWord) || preg_match('/^[\\.:,\'_-]+$/', $strWord)) {
             continue;
         }
         if (preg_match('/^[\':,]/', $strWord)) {
             $strWord = substr($strWord, 1);
         }
         if (preg_match('/[\':,.]$/', $strWord)) {
             $strWord = substr($strWord, 0, -1);
         }
         if (isset($arrIndex[$strWord])) {
             $arrIndex[$strWord]++;
             continue;
         }
         $arrIndex[$strWord] = 1;
     }
     // Remove existing index
     $objDatabase->prepare("DELETE FROM tl_search_index WHERE pid=?")->execute($intInsertId);
     // Create new index
     foreach ($arrIndex as $k => $v) {
         $objDatabase->prepare("INSERT INTO tl_search_index (pid, word, relevance, language) VALUES (?, ?, ?, ?)")->execute($intInsertId, $k, $v, $arrData['language']);
     }
     return true;
 }
예제 #14
0
 /**
  * Validate input and set value
  *
  * @param mixed $varInput
  *
  * @return string
  */
 protected function validator($varInput)
 {
     $this->blnSubmitInput = false;
     if (($varInput == '' || $varInput == '*****') && $this->varValue != '') {
         return '*****';
     }
     if (Utf8::strlen($varInput) < \Config::get('minPasswordLength')) {
         $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['passwordLength'], \Config::get('minPasswordLength')));
     }
     if ($varInput != $this->getPost($this->strName . '_confirm')) {
         $this->addError($GLOBALS['TL_LANG']['ERR']['passwordMatch']);
     }
     if ($varInput == $GLOBALS['TL_USERNAME']) {
         $this->addError($GLOBALS['TL_LANG']['ERR']['passwordName']);
     }
     $varInput = parent::validator($varInput);
     if (!$this->hasErrors()) {
         $this->blnSubmitInput = true;
         \Message::addConfirmation($GLOBALS['TL_LANG']['MSC']['pw_changed']);
         return \Encryption::hash($varInput);
     }
     return '';
 }
예제 #15
0
 /**
  * Validates the password length and creates the password hash.
  *
  * @param string $password
  *
  * @return string
  *
  * @throws InvalidArgumentException
  */
 private function validateAndHashPassword($password)
 {
     $framework = $this->getContainer()->get('contao.framework');
     $framework->initialize();
     /** @var Config $confirm */
     $config = $framework->getAdapter(Config::class);
     $passwordLength = $config->get('minPasswordLength') ?: 8;
     if (Utf8::strlen($password) < $passwordLength) {
         throw new InvalidArgumentException(sprintf('The password must be at least %s characters long.', $passwordLength));
     }
     /** @var Encryption $encryption */
     $encryption = $framework->getAdapter(Encryption::class);
     return $encryption->hash($password);
 }