Beispiel #1
0
 /**
  * @param IFile $file
  * @param bool $foldersFirst
  * @return int A negative value if the current file should be placed before $file,
  * zero (0) if they are equals, a positive value otherwise.
  */
 public function compareTo(IFile $file, $foldersFirst = false)
 {
     if ($foldersFirst) {
         $isDirThis = $this->isDirectory();
         $isDirFile = $file->isDirectory();
         if ($isDirThis && !$isDirFile) {
             return -1;
         } else {
             if ($isDirFile && !$isDirThis) {
                 return 1;
             }
         }
     }
     $urlParts = $file->getURLComponents();
     $urlParts['path'] = $file->getPathFromRoot();
     //needed to resolve the path (if relative)
     $absolutePathFile = AdvancedPathLib::buildURL($urlParts);
     $urlParts = $this->getURLComponents();
     $urlParts['path'] = $this->getPathFromRoot();
     //needed to resolve the path (if relative)
     $absolutePathThis = AdvancedPathLib::buildURL($urlParts);
     return utf8_strcasecmp($absolutePathThis, $absolutePathFile);
 }
Beispiel #2
0
 /**
  * UTF-8/LOCALE aware alternative to strcasecmp
  * A case insensitive string comparison
  *
  * @param   string  $str1    string 1 to compare
  * @param   string  $str2    string 2 to compare
  * @param   mixed   $locale  The locale used by strcoll or false to use classical comparison
  *
  * @return  integer   < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
  *
  * @see     http://www.php.net/strcasecmp
  * @see     http://www.php.net/strcoll
  * @see     http://www.php.net/setlocale
  * @since   11.1
  */
 public static function strcasecmp($str1, $str2, $locale = false)
 {
     if ($locale) {
         // Get current locale
         $locale0 = setlocale(LC_COLLATE, 0);
         if (!($locale = setlocale(LC_COLLATE, $locale))) {
             $locale = $locale0;
         }
         // See if we have successfully set locale to UTF-8
         if (!stristr($locale, 'UTF-8') && stristr($locale, '_') && preg_match('~\\.(\\d+)$~', $locale, $m)) {
             $encoding = 'CP' . $m[1];
         } elseif (stristr($locale, 'UTF-8')) {
             $encoding = 'UTF-8';
         } else {
             $encoding = 'nonrecodable';
         }
         // If we successfully set encoding it to utf-8 or encoding is sth weird don't recode
         if ($encoding == 'UTF-8' || $encoding == 'nonrecodable') {
             return strcoll(utf8_strtolower($str1), utf8_strtolower($str2));
         } else {
             return strcoll(self::transcode(utf8_strtolower($str1), 'UTF-8', $encoding), self::transcode(utf8_strtolower($str2), 'UTF-8', $encoding));
         }
     } else {
         return utf8_strcasecmp($str1, $str2);
     }
 }
/** compare two arrays by the title member (for sorting modules)
 *
 * @param array $a
 * @param array $b
 * $return int indicating the ordering of $a and $b like strcmp()
 */
function modulemanager_cmp($a, $b)
{
    return utf8_strcasecmp($a['title'], $b['title']);
}
 function testLinefeed()
 {
     $strX = "iñtërnâtiôn\nàlizætiøn";
     $strY = "IÑTËRNÂTIÔN\nÀLIZÆTIØN";
     $this->assertTrue(utf8_strcasecmp($strX, $strY) == 0);
 }
/** perform actual update to version 2011051100
 *
 * this is a substantial change in the database: we (finally) standardise on UTF-8
 * including the database. Up until now we still only have a choice of exactly one
 * database driver: MySQL. Therefore the upgrade we do here can be more or less
 * MySQL-specific. (So much for database-independency).
 *
 * What needs to be done here?
 *
 * The most important task (in fact: the only task) is to change the collation (and
 * implicitly the default charset) to utf8_unicode_ci (4.1.x <= MySQL < 5.5.2) or
 * utf8mb4_unicode_ci (MySQL 5.5.3+). See {@link mysql.class.php} for more information
 * on these UTF-8 & MySQL issues.
 *
 * Strategy here is as follows.
 * <code>
 * for all 'our' tables (ie. "LIKE '{$prefix}%'" do
 *    if table default charset is already utf8 (or utf8mb4)
 *        continue;
 *    for appropriate columns in this table
 *        change column type to binary
 *        change column type back to non-binary with correct charset and collation
 *    if no trouble sofar
 *        change default charset/collation of the table too
 *    else
 *        return failure
 * return success
 * </code>
 *
 * This way we _might_ be able to work our way through huge tables: if the PHP
 * max processing time kicks in, we can rerun the upgrade and start (again) with
 * the table we had in our hands the previous time. I don't expect this to happen,
 * but it still the way to do it IMHO.
 *
 * Note that I assume that I cannot change the default charset of the DATABASE
 * for the same reason the Installation Wizard expects the database to be ready
 * before installation commences. (I cannot be sure that I have the privilege to
 * execute 'ALTER DATABASE $db_name DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci').
 *
 * A useful reference for solving this problem of converting to utf8 can be found
 * here: http://codex.wordpress.org/Converting_Database_Character_Sets.
 *
 * In the case of W@S we do not have to deal with enum-fields because those are not used
 * at this time. In fact it boils down to changing char, varchar, text and longtext.
 *
 * Let goforit...
 *
 * @param object &$output collects the html output
 * @return bool TRUE on success, FALSE otherwise
 */
function update_core_2011051100(&$output)
{
    global $CFG, $DB;
    // 0 -- get outta here when already upgraded
    $version = 2011051100;
    if ($CFG->version >= $version) {
        return TRUE;
    }
    // 1 -- can we do anything at all with upgrading to UTF-8 and all?
    $utf8_level = isset($DB->utf8_support) ? $DB->utf8_support : FALSE;
    if ($utf8_level === FALSE) {
        $msg = sprintf('%s(): cannot determine UTF-8 support in MySQL: utf8_level is not 0, 3 or 4', __FUNCTION__);
        logger($msg);
        $output->add_message(htmlspecialchars($msg));
        $output->add_message(t('update_core_error', 'admin', array('{VERSION}' => strval($version))));
        return FALSE;
    } elseif ($utf8_level == 0) {
        $db_version = mysql_get_server_info();
        logger(sprintf('%s(): MySQL \'%s\' too old for UTF-8 update', __FUNCTION__, $db_version));
        $params = array('{VERSION}' => $db_version);
        $output->add_message(t('warning_mysql_obsolete', 'i_install', $params));
        return update_core_version($output, $version);
    }
    // 2A -- prepare to step through all tables and all columns changing collation (and implicit charset)
    $charset = $utf8_level == 3 ? 'utf8' : 'utf8mb4';
    $collation = $charset . '_unicode_ci';
    $pattern = str_replace(array('_', '%'), array('\\_', '\\%'), $DB->escape($DB->prefix)) . '%';
    // e.g. 'was\_%'
    $sql = sprintf("SHOW TABLE STATUS LIKE '%s'", $pattern);
    if (($DBResult = $DB->query($sql)) === FALSE) {
        $msg = sprintf('%s(): cannot show tables: %d/%s', __FUNCTION__, $DB->errno, $DB->error);
        logger($msg);
        $output->add_message(htmlspecialchars($msg));
        $output->add_message(t('update_core_error', 'admin', array('{VERSION}' => strval($version))));
        return FALSE;
    }
    $tables = $DBResult->fetch_all_assoc('Name');
    $DBResult->close();
    $overtime = max(intval(ini_get('max_execution_time')), 30);
    // request this additional processing time after a table
    // 2B -- visit all tables
    foreach ($tables as $table) {
        if (isset($table['Collation']) && utf8_strcasecmp($table['Collation'], $collation) == 0) {
            logger(sprintf('%s(): table \'%s\' is already \'%s\'', __FUNCTION__, $table['Name'], $collation), WLOG_DEBUG);
            continue;
            // somehow someone already changed this table; carry on with the next one
        }
        // 3A -- prepare to step through all columns of this table
        $sql = sprintf('SHOW FULL COLUMNS FROM `%s`', $table['Name']);
        if (($DBResult = $DB->query($sql)) === FALSE) {
            $msg = sprintf('%s(): cannot show columns from %s: %d/%s', __FUNCTION__, $table['Name'], $DB->errno, $DB->error);
            logger($msg);
            $output->add_message(htmlspecialchars($msg));
            $output->add_message(t('update_core_error', 'admin', array('{VERSION}' => strval($version))));
            return FALSE;
        }
        $columns = $DBResult->fetch_all_assoc('Field');
        // 3B -- visit all columns in this table
        foreach ($columns as $column) {
            if (isset($column['Collation'])) {
                if (is_null($column['Collation'])) {
                    continue;
                    // nothing to do; no collation to change
                } elseif (utf8_strcasecmp($column['Collation'], $collation) == 0) {
                    logger(sprintf('%s(): column \'%s.%s\' is already converted to \'%s\'', __FUNCTION__, $table['Name'], $column['Field'], $collation), WLOG_DEBUG);
                    continue;
                    // somehow someone already changed this column; carry on with the next one
                }
            } else {
                continue;
                // this field has no collation whatsoever. Weird but we'll let it pass.
            }
            $sql1 = sprintf('ALTER TABLE `%s` CHANGE `%s` `%s` ', $table['Name'], $column['Field'], $column['Field']);
            $sql2 = $sql1;
            $vtype = explode("(", $column['Type']);
            // split 'varchar(n)' into components
            switch (strtolower($vtype[0])) {
                case 'varchar':
                    $len = intval($vtype[1]);
                    $sql1 .= sprintf('VARBINARY(%d)', $len);
                    $sql2 .= sprintf('VARCHAR(%d)', $len);
                    break;
                case 'char':
                    $len = intval($vtype[1]);
                    $sql1 .= sprintf('BINARY(%d)', $len);
                    $sql2 .= sprintf('CHAR(%d)', $len);
                    break;
                case 'text':
                    $sql1 .= 'BLOB';
                    $sql2 .= 'TEXT';
                    break;
                case 'longtext':
                    $sql1 .= 'LONGBLOB';
                    $sql2 .= 'LONGTEXT';
                    break;
                default:
                    logger(sprintf('%s(): cannot handle \'%s.%s\' type \'%s\'; skipping', __FUNCTION__, $table['Name'], $column['Field'], $vtype[0]), WLOG_DEBUG);
                    continue;
                    break;
            }
            $sql2 .= sprintf(' CHARACTER SET %s COLLATE %s', $charset, $collation);
            $sql2 .= $column['Null'] == 'YES' ? ' NULL' : ' NOT NULL';
            $sql2 .= is_null($column['Default']) ? '' : sprintf(' DEFAULT \'%s\'', $DB->escape($column['Default']));
            $sql2 .= empty($column['Comment']) ? '' : sprintf(' COMMENT \'%s\'', $DB->escape($column['Comment']));
            // Do back-and-forth in one go so we don't write to 'log_messages' while that table is being converted
            // We report any errors/do logging after we're back on track again
            $retval1 = $DB->exec($sql1);
            $errno1 = $DB->errno;
            $error1 = $DB->error;
            // text (latin1) -> binary
            $retval2 = $DB->exec($sql2);
            $errno2 = $DB->errno;
            $error2 = $DB->error;
            // binary -> text (utf8)
            if ($retval1 === FALSE || $retval2 === FALSE) {
                // oops, failure! gotta get out of this place!
                $msg = sprintf('%s(): cannot change \'%s.%s\': \'%s\': \'%d/%s\', \'%s\': \'%d/%s\'; bailing out', __FUNCTION__, $table['Name'], $column['Field'], $sql1, $errno1, $error1, $sql2, $errno2, $error2);
                logger($msg);
                $output->add_message(htmlspecialchars($msg));
                $output->add_message(t('update_core_error', 'admin', array('{VERSION}' => strval($version))));
                return FALSE;
            } else {
                logger(sprintf('%s(): alter column \'%s.%s\': changed collation from \'%s\' to  \'%s\'', __FUNCTION__, $table['Name'], $column['Field'], $column['Collation'], $collation), WLOG_DEBUG);
            }
        }
        // Only if all columns went OK, we change the table; this is a quick and dirty sentinel to work
        // through a long converstion (at worst we do 1 table per round) Eventually the conversion will be complete...
        $sql = sprintf('ALTER TABLE `%s` DEFAULT CHARSET %s COLLATE %s', $table['Name'], $charset, $collation);
        if ($DB->exec($sql) === FALSE) {
            $msg = sprintf('%s(): cannot alter \'%s\' with \'%s\': %d/%s; bailing out', __FUNCTION__, $table['Name'], $sql, $DB->errno, $DB->error);
            logger($msg);
            $output->add_message(htmlspecialchars($msg));
            $output->add_message(t('update_core_error', 'admin', array('{VERSION}' => strval($version))));
            return FALSE;
        } else {
            logger(sprintf('%s(): alter table \'%s\': changed collation from \'%s\' to  \'%s\'', __FUNCTION__, $table['Name'], $table['Collation'], $collation), WLOG_DEBUG);
        }
        @set_time_limit($overtime);
        // try to get additional processing time after every processed table
    }
    return update_core_version($output, $version);
}
 /** convert a fielddef array to a MySQL specific column definition
  *
  * this creates a MySQL specific column definition based on a generic field
  * description. The following keywords are recognised:
  *  - name: the name of the field (required)
  *  - type: the generic type of the field (see table below for supported types) (required)
  *  - length: the size of a numeric field or the length of a textual field
  *  - decimals: the number of decimals in real numbers (implies length)
  *  - unsigned: used for numeric fields that don't need negative values (see note 5 below)
  *  - notnull: if true, the field is not allowed/able to contain the NULL value
  *  - default: the default value for the field
  *  - enum_values: an array with allowable values for the enum field
  *  - comment: a string that can be used to document the field definition
  *
  * The generic field types are mapped to actual MySQL data types via a lookup table.
  * Most types have a number of  boolean flags which indicate how the field definition
  * must be interpreted. Entries with an empty type are considered special cases.
  *
  *  - len = 1: look for a length parameter and use it if it is defined.
  *  - dec = 1: look for a decimals parameter and use it if it is defined. Implies len.
  *  - unsigned = 1: look for an unsigned parameter and use it if it is defined and true (see note 5 below).
  *  - default = 1: look for a default parameter, and use it if it is defined.
  *  - quote = 1: if a default is allowed AND defined, use single quotes + escaped string.
  *
  * Note 1: a 1 in the table means that the field type _allows_ the corresponding parameter,
  * and 0 means that this parameter is NOT allowed. It doesn't say anything about parameters
  * being _required_ (e.g. a varchar must have a length). It is the responsability of the
  * author of the field definition to provide all necessary parameters.
  *
  * Note 2: enum_values are not used at this time; an enum-field simply maps to a
  * varchar field and that's it. Adding the enum_values to a data definition does help
  * to document the purpose of the field. The reason for not (yet) implementing enums
  * in full is the issues associated with the translations in the UI. Furthermore, using
  * native enums in MySQL is a royal PITA. For now the application should know what it is
  * doing when using and updating enums in a table.
  *
  * Note 3: at this time it is not possible to set the default value of a text-type field
  * to the string consisting of the letters N, U, L and L: that caseinsensitive string is
  * always interpreted as the NULL-value in the database, ie. it yields "DEFAULT NULL" and
  * not "DEFAULT 'NULL'" or "DEFAULT 'Null'" or "DEFAULT 'null'".
  *
  * Note 4: even though comments may or may not be stored in the MySQL database, the corresponding
  * COMMENT-clauses are generated, if only for documentation/debugging purposes. These
  * clauses are correctly parsed by MySQL but they are subsequently discarded in old MySQL-versions.
  *
  * Note 5:
  * As of version 2009051401 (0.0.5) the parameter 'unsigned' is deprecated.
  * This is because even though MySQL implements an unsigned attribute for numeric fields,
  * other RDBMSs might not. Therefore we stay away from this MySQL-specific construct as
  * much as possible. Also, the translation from the 'serial' fieldrtype no longer adds
  * the unsigned attribute to the actual MySQL definition.
  *
  * @param array an array that describes a field in a generic way
  * @return bool|string FALSE on failure or a MySQL-specific string defining the column
  * @todo should we allow both int and integer?
  * @todo 'enum' type equivalent with varchar, enum_values[] array is not used at all, only as a form of documentation
  */
 function column_definition($fielddef)
 {
     static $type_map = array('short' => array('type' => 'SMALLINT', 'len' => 1, 'dec' => 0, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'int' => array('type' => 'INT', 'len' => 1, 'dec' => 0, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'long' => array('type' => 'BIGINT', 'len' => 1, 'dec' => 0, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'float' => array('type' => 'FLOAT', 'len' => 1, 'dec' => 1, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'double' => array('type' => 'DOUBLE', 'len' => 1, 'dec' => 1, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'decimal' => array('type' => 'DECIMAL', 'len' => 1, 'dec' => 1, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'number' => array('type' => 'DECIMAL', 'len' => 1, 'dec' => 1, 'unsigned' => 1, 'default' => 1, 'quote' => 0), 'varchar' => array('type' => 'VARCHAR', 'len' => 1, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'enum' => array('type' => 'VARCHAR', 'len' => 1, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'char' => array('type' => 'CHAR', 'len' => 1, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'text' => array('type' => 'TEXT', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 0, 'quote' => 0), 'longtext' => array('type' => 'LONGTEXT', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 0, 'quote' => 0), 'blob' => array('type' => 'BLOB', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 0, 'quote' => 0), 'longblob' => array('type' => 'LONGBLOB', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 0, 'quote' => 0), 'date' => array('type' => 'DATE', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'time' => array('type' => 'TIME', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'datetime' => array('type' => 'DATETIME', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'timestamp' => array('type' => 'TIMESTAMP', 'len' => 0, 'dec' => 0, 'unsigned' => 0, 'default' => 1, 'quote' => 1), 'serial' => array('type' => ''), 'bool' => array('type' => ''));
     if (!isset($type_map[$fielddef['type']])) {
         trigger_error('internal error: unknown field type \'' . $fielddef['type'] . '\'', E_USER_ERROR);
         return FALSE;
     }
     $column_def = $fielddef['name'] . ' ';
     // collect the output, start with the field's name
     $field = $type_map[$fielddef['type']];
     if (empty($field['type'])) {
         // special case, e.g. bool or serial
         switch ($fielddef['type']) {
             case 'serial':
                 $column_def .= 'INT NOT NULL AUTO_INCREMENT UNIQUE';
                 // Note: no implied PRIMARY KEY
                 break;
             case 'bool':
                 $column_def .= 'TINYINT(1)';
                 if (isset($fielddef['notnull']) && $fielddef['notnull']) {
                     $column_def .= " NOT NULL";
                 }
                 if (isset($fielddef['default'])) {
                     $column_def .= ' DEFAULT ';
                     if (is_null($fielddef['default']) || strcasecmp($fielddef['default'], 'null') == 0) {
                         $column_def .= 'NULL';
                     } else {
                         $column_def .= $fielddef['default'] ? SQL_TRUE : SQL_FALSE;
                     }
                 }
                 break;
             default:
                 trigger_error('internal error: \'' . $fielddef['name'] . '\' is no special case', E_USER_ERROR);
                 return FALSE;
                 break;
         }
     } else {
         $column_def .= $field['type'];
         /* if this field is allowed to have a length, maybe pickup the specified length and optional decimals */
         if ($field['len']) {
             if (isset($fielddef['length'])) {
                 if ($field['dec'] && isset($fielddef['decimals'])) {
                     $column_def .= '(' . $fielddef['length'] . ',' . $fielddef['decimals'] . ')';
                 } else {
                     $column_def .= '(' . $fielddef['length'] . ')';
                 }
             }
         }
         if ($field['unsigned']) {
             // See note 5 above: 'unsigned' is deprecated.
             if (isset($fielddef['unsigned']) && $fielddef['unsigned']) {
                 $column_def .= " UNSIGNED";
             }
         }
         if (isset($fielddef['notnull']) && $fielddef['notnull']) {
             $column_def .= " NOT NULL";
         }
         if ($field['default']) {
             if (isset($fielddef['default'])) {
                 if (utf8_strcasecmp($fielddef['default'], 'null') == 0) {
                     // see the note above
                     $column_def .= ' DEFAULT NULL';
                 } elseif ($field['quote']) {
                     $column_def .= ' DEFAULT \'' . $this->escape($fielddef['default']) . '\'';
                 } else {
                     $column_def .= ' DEFAULT ' . $fielddef['default'];
                 }
             }
         }
     }
     if (isset($fielddef['comment'])) {
         $column_def .= ' COMMENT \'' . $this->escape($fielddef['comment']) . '\'';
     }
     return $column_def;
 }
Beispiel #7
0
 public function check_username($username, $errors, $exclude_id = null)
 {
     // Include UTF-8 function
     require_once ForumEnv::get('FEATHER_ROOT') . 'featherbb/Helpers/utf8/strcasecmp.php';
     translate('register');
     translate('prof_reg');
     // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames)
     $username = preg_replace('%\\s+%s', ' ', $username);
     // Validate username
     if (Utils::strlen($username) < 2) {
         $errors[] = __('Username too short');
     } elseif (Utils::strlen($username) > 25) {
         // This usually doesn't happen since the form element only accepts 25 characters
         $errors[] = __('Username too long');
     } elseif (!strcasecmp($username, 'Guest') || !utf8_strcasecmp($username, __('Guest'))) {
         $errors[] = __('Username guest');
     } elseif (filter_var($username, FILTER_VALIDATE_IP)) {
         $errors[] = __('Username IP');
     } elseif ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) {
         $errors[] = __('Username reserved chars');
     } elseif (preg_match('%(?:\\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\\*|topic|post|forum|user)\\]|\\[(?:img|url|quote|list)=)%i', $username)) {
         $errors[] = __('Username BBCode');
     }
     // Check username for any censored words
     if (ForumSettings::get('o_censoring') == '1' && Utils::censor($username) != $username) {
         $errors[] = __('Username censor');
     }
     // Check that the username (or a too similar username) is not already registered
     $query = !is_null($exclude_id) ? ' AND id!=' . $exclude_id : '';
     $result = DB::for_table('online')->raw_query('SELECT username FROM ' . ForumSettings::get('db_prefix') . 'users WHERE (UPPER(username)=UPPER(:username1) OR UPPER(username)=UPPER(:username2)) AND id>1' . $query, array(':username1' => $username, ':username2' => Utils::ucp_preg_replace('%[^\\p{L}\\p{N}]%u', '', $username)))->find_one();
     if ($result) {
         $busy = $result['username'];
         $errors[] = __('Username dupe 1') . ' ' . Utils::escape($busy) . '. ' . __('Username dupe 2');
     }
     // Check username for any banned usernames
     foreach (Container::get('bans') as $cur_ban) {
         if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) {
             $errors[] = __('Banned username');
             break;
         }
     }
     return $errors;
 }
Beispiel #8
0
 /**
  * UTF-8 aware alternative to strcasecmp
  * A case insensivite string comparison
  *
  * @static
  * @access public
  * @param string string 1 to compare
  * @param string string 2 to compare
  * @return int < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
  * @see http://www.php.net/strcasecmp
  */
 public static function strcasecmp($str1, $str2)
 {
     jimport('phputf8.strcasecmp');
     return utf8_strcasecmp($str1, $str2);
 }
function check_username($username, $exclude_id = null)
{
    global $db, $pun_config, $errors, $lang_prof_reg, $lang_register, $lang_common, $pun_bans;
    // Include UTF-8 function
    require_once PUN_ROOT . 'include/utf8/strcasecmp.php';
    // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames)
    $username = preg_replace('%\\s+%s', ' ', $username);
    // Validate username
    if (pun_strlen($username) < 2) {
        $errors[] = $lang_prof_reg['Username too short'];
    } else {
        if (pun_strlen($username) > 25) {
            // This usually doesn't happen since the form element only accepts 25 characters
            $errors[] = $lang_prof_reg['Username too long'];
        } else {
            if (!strcasecmp($username, 'Guest') || !utf8_strcasecmp($username, $lang_common['Guest'])) {
                $errors[] = $lang_prof_reg['Username guest'];
            } else {
                if (preg_match('%[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}%', $username) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $username)) {
                    $errors[] = $lang_prof_reg['Username IP'];
                } else {
                    if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) {
                        $errors[] = $lang_prof_reg['Username reserved chars'];
                    } else {
                        if (preg_match('%(?:\\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\\*|topic|post|forum|user)\\]|\\[(?:img|url|quote|list)=)%i', $username)) {
                            $errors[] = $lang_prof_reg['Username BBCode'];
                        }
                    }
                }
            }
        }
    }
    // Check username for any censored words
    if ($pun_config['o_censoring'] == '1' && censor_words($username) != $username) {
        $errors[] = $lang_register['Username censor'];
    }
    // Check that the username (or a too similar username) is not already registered
    $query = !is_null($exclude_id) ? ' AND id!=' . $exclude_id : '';
    $result = $db->query('SELECT username FROM ' . $db->prefix . 'users WHERE (UPPER(username)=UPPER(\'' . $db->escape($username) . '\') OR UPPER(username)=UPPER(\'' . $db->escape(ucp_preg_replace('%[^\\p{L}\\p{N}]%u', '', $username)) . '\')) AND id>1' . $query) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
    if ($db->num_rows($result)) {
        $busy = $db->result($result);
        $errors[] = $lang_register['Username dupe 1'] . ' ' . pun_htmlspecialchars($busy) . '. ' . $lang_register['Username dupe 2'];
    }
    // Check username for any banned usernames
    foreach ($pun_bans as $cur_ban) {
        if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) {
            $errors[] = $lang_prof_reg['Banned username'];
            break;
        }
    }
}
Beispiel #10
0
function check_username($username, $exclude_id = null)
{
    global $db, $luna_config, $errors, $luna_bans;
    // Include UTF-8 function
    require_once FORUM_ROOT . 'include/utf8/strcasecmp.php';
    // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames)
    $username = preg_replace('%\\s+%s', ' ', $username);
    // Validate username
    if (luna_strlen($username) < 2) {
        $errors[] = __('Usernames must be at least 2 characters long. Please choose another (longer) username.', 'luna');
    } elseif (luna_strlen($username) > 25) {
        // This usually doesn't happen since the form element only accepts 25 characters
        $errors[] = __('Usernames must not be more than 25 characters long. Please choose another (shorter) username.', 'luna');
    } elseif (!strcasecmp($username, 'Guest') || !utf8_strcasecmp($username, __('Guest', 'luna'))) {
        $errors[] = __('The username guest is reserved. Please choose another username.', 'luna');
    } elseif (preg_match('%[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}%', $username) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $username)) {
        $errors[] = __('Usernames may not be in the form of an IP address. Please choose another username.', 'luna');
    } elseif ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) {
        $errors[] = __('Usernames may not contain all the characters \', " and [ or ] at once. Please choose another username.', 'luna');
    } elseif (preg_match('%(?:\\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\\*|topic|post|forum|user)\\]|\\[(?:img|url|quote|list)=)%i', $username)) {
        $errors[] = __('Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please choose another username.', 'luna');
    }
    // Check username for any censored words
    if ($luna_config['o_censoring'] == '1' && censor_words($username) != $username) {
        $errors[] = __('The username you entered contains one or more censored words. Please choose a different username.', 'luna');
    }
    // Check that the username (or a too similar username) is not already registered
    $query = !is_null($exclude_id) ? ' AND id!=' . $exclude_id : '';
    $result = $db->query('SELECT username FROM ' . $db->prefix . 'users WHERE (UPPER(username)=UPPER(\'' . $db->escape($username) . '\') OR UPPER(username)=UPPER(\'' . $db->escape(ucp_preg_replace('%[^\\p{L}\\p{N}]%u', '', $username)) . '\')) AND id>1' . $query) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
    if ($db->num_rows($result)) {
        $busy = $db->result($result);
        $errors[] = __('Someone is already registered with the username', 'luna') . ' ' . luna_htmlspecialchars($busy) . '. ' . __('The username you entered is too similar. The username must differ from that by at least one alphanumerical character (a-z or 0-9). Please choose a different username.', 'luna');
    }
    // Check username for any banned usernames
    foreach ($luna_bans as $cur_ban) {
        if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) {
            $errors[] = __('The username you entered is banned in this forum. Please choose another username.', 'luna');
            break;
        }
    }
}
Beispiel #11
0
 public static function strcasecmp($str1, $str2, $locale = false)
 {
     if ($locale) {
         $locale0 = setlocale(LC_COLLATE, 0);
         if (!($locale = setlocale(LC_COLLATE, $locale))) {
             $locale = $locale0;
         }
         if (!stristr($locale, 'UTF-8') && stristr($locale, '_') && preg_match('~\\.(\\d+)$~', $locale, $m)) {
             $encoding = 'CP' . $m[1];
         } elseif (stristr($locale, 'UTF-8')) {
             $encoding = 'UTF-8';
         } else {
             $encoding = 'nonrecodable';
         }
         if ($encoding == 'UTF-8' || $encoding == 'nonrecodable') {
             return strcoll(utf8_strtolower($str1), utf8_strtolower($str2));
         } else {
             return strcoll(self::transcode(utf8_strtolower($str1), 'UTF-8', $encoding), self::transcode(utf8_strtolower($str2), 'UTF-8', $encoding));
         }
     } else {
         return utf8_strcasecmp($str1, $str2);
     }
 }
 /** check if the user accepts the licences
  *
  * This is the companion routine for {@link show_dialog_license()}.
  * It checks whether the user dutyfully typed 'I agree'.
  * Note that we check caseINsensitive, so 'i agree' is acceptable, as is 'I aGrEe'.
  * Also note that we accept non-ascii UTF-8, say "J'accept'ee" or "J'ACCEPT'EE" 
  * which  has an e-acute. Case folding to lowercase accepts all those variants.
  *
  * @return bool TRUE on success, otherwise FALSE + error information in $this->messages array
  */
 function check_license()
 {
     $iagree = $this->t('dialog_license_i_agree');
     $license = trim($this->get_utf8_parameter_string($_POST, 'license'));
     $_SESSION['INSTALL']['license_accepted'] = utf8_strcasecmp(trim($iagree), $license) == 0 ? TRUE : FALSE;
     $retval = $_SESSION['INSTALL']['license_accepted'];
     if ($retval != TRUE) {
         $a = array('{IAGREE}' => $iagree);
         $this->messages[] = $this->t('dialog_license_you_must_accept', $a);
     }
     return $retval;
 }
Beispiel #13
0
function check_username($username, $exclude_id = null)
{
    global $db, $panther_config, $errors, $lang_prof_reg, $lang_register, $lang_common, $panther_bans;
    // Include UTF-8 function
    require_once PANTHER_ROOT . 'include/utf8/strcasecmp.php';
    // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames)
    $username = preg_replace('%\\s+%s', ' ', $username);
    // Validate username
    if (panther_strlen($username) < 2) {
        $errors[] = $lang_prof_reg['Username too short'];
    } else {
        if (panther_strlen($username) > 25) {
            // This usually doesn't happen since the form element only accepts 25 characters
            $errors[] = $lang_prof_reg['Username too long'];
        } else {
            if (!strcasecmp($username, 'Guest') || !utf8_strcasecmp($username, $lang_common['Guest'])) {
                $errors[] = $lang_prof_reg['Username guest'];
            } else {
                if (preg_match('%[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}%', $username) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $username)) {
                    $errors[] = $lang_prof_reg['Username IP'];
                } else {
                    if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) {
                        $errors[] = $lang_prof_reg['Username reserved chars'];
                    } else {
                        if (preg_match('%(?:\\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\\*|topic|post|forum|user)\\]|\\[(?:img|url|quote|list)=)%i', $username)) {
                            $errors[] = $lang_prof_reg['Username BBCode'];
                        }
                    }
                }
            }
        }
    }
    // Check username for any censored words
    if ($panther_config['o_censoring'] == '1' && censor_words($username) != $username) {
        $errors[] = $lang_register['Username censor'];
    }
    $where_cond = '(UPPER(username)=UPPER(:username) OR UPPER(username)=UPPER(:username2)) AND id>1';
    $data = array(':username' => $username, ':username2' => ucp_preg_replace('%[^\\p{L}\\p{N}]%u', '', $username));
    // Check that the username (or a too similar username) is not already registered
    if (!is_null($exclude_id)) {
        $where_cond .= ' AND id!=:id';
        $data[':id'] = $exclude_id;
    }
    $ps = $db->select('users', 'username', $data, $where_cond);
    if ($ps->rowCount()) {
        $busy = $ps->fetchColumn();
        $errors[] = $lang_register['Username dupe 1'] . ' ' . $busy . '. ' . $lang_register['Username dupe 2'];
    }
    // Check username for any banned usernames
    foreach ($panther_bans as $cur_ban) {
        if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) {
            $errors[] = $lang_prof_reg['Banned username'];
            break;
        }
    }
}