/** * Метод возвращает экземпляр класса-хранилища маппингов. * Может быть переопределён в config.ini */ private static final function inst() { if (isset(self::$inst)) { return self::$inst; //---- } /* * Получим название класса */ $class = ConfigIni::mappingStorage(); /* * Класс совпадает с базовым? */ if (__CLASS__ == $class) { return self::$inst = new MappingStorage(); } /* * Нам передан класс, который отличается от SDK */ $classPath = Autoload::inst()->getClassPath($class); if (!PsCheck::isNotEmptyString($classPath)) { return PsUtil::raise('Не удалось найти класс хранилища маппингов [{}]', $class); } /* * Указанный класс должен быть наследником данного */ if (!PsUtil::isInstanceOf($class, __CLASS__)) { return PsUtil::raise('Указанное хранилище маппингов [{}] не является наследником класса [{}]', $class, __CLASS__); } return self::$inst = new $class(); }
/** * Получает числовой код типа картинки * * @param mixed $plain - тип|расширение|mime * @return int */ public static function getType($plain) { if (PsCheck::isInt($plain)) { $temp = 1 * $plain; check_condition(in_array($temp, self::TYPES()), "Тип картинок [{$plain}] запрещён"); return $temp; } if (PsCheck::isNotEmptyString($plain)) { $temp = lowertrim($plain); $byExt = in_array($temp, self::EXTS()); $byMime = !$byExt && in_array($temp, self::MIMES()); if ($byExt || $byMime) { foreach (self::$TYPE2EXT as $type => $exts) { if ($byExt) { //Поиск по расширениям if (in_array($temp, (array) $exts)) { return $type; } } else { //Поиск по mime типам if ($temp == strtolower(image_type_to_mime_type($type))) { return $type; } } } } } raise_error("Не удалось определить тип картинки по идентификатору [{$plain}], либо картинка онтосится к запрещённым типам."); }
public function getTables($scope = ENTITY_SCOPE_ALL) { if (!is_array($this->TABLES)) { $this->TABLES[ENTITY_SCOPE_ALL] = array(); $this->TABLES[ENTITY_SCOPE_SDK] = array(); $this->TABLES[ENTITY_SCOPE_PROJ] = array(); $tables = PsTable::all(); $tablesNotConfigured = array(); //Таблицы, описанные в ini, но не сконфигурированные foreach (DbIni::getTables() as $tableName) { if (!array_key_exists($tableName, $tables)) { continue; //--- } /* @var $table PsTable */ $table = $tables[$tableName]; if ($table->isConfigured()) { $this->TABLES[ENTITY_SCOPE_ALL][$tableName] = $table; $this->TABLES[$table->getScope()][$tableName] = $table; unset($tables[$tableName]); } else { $tablesNotConfigured[ENTITY_SCOPE_ALL][$tableName] = $table; $tablesNotConfigured[$table->getScope()][$tableName] = $table; } } foreach ($tablesNotConfigured as $_scope => $_tables) { $this->TABLES[$_scope] = array_merge($this->TABLES[$_scope], $_tables); } foreach ($tables as $tableName => $table) { $this->TABLES[ENTITY_SCOPE_ALL][$tableName] = $table; $this->TABLES[$table->getScope()][$tableName] = $table; } } return $this->TABLES[PsCheck::scope($scope)]; }
/** * Метод возвращает экземпляр кеша для класса * * @param string название класса * @return SimpleDataCache */ public static function getCache($class) { if (array_key_exists($class, self::$CACHES)) { return self::$CACHES[$class]; } PsLogger::inst(__CLASS__)->info('+ Cache for [{}]', PsCheck::notEmptyString($class)); return self::$CACHES[$class] = new SimpleDataCache(); }
/** @return PSSelect */ public function setLimit($limit) { if (is_array($limit)) { $this->limit = $limit; } else { $this->limit = PsCheck::intOrNull($limit); $this->limit = is_null($this->limit) || $this->limit <= 0 ? null : $this->limit; } return $this; }
function __construct($name, $value, $asBind = true, $operator = self::DEFAULT_OPERATOR, array $extraBinds = array()) { $this->name = PsCheck::tableColName($name); $this->value = $asBind ? PsCheck::queryBindParam($value, $name) : PsCheck::queryPlainExpression($value, $name); $this->asBind = $asBind; $this->operator = PsCheck::notEmptyString($operator); foreach ($extraBinds as $bindParam) { $this->extraBinds[] = PsCheck::queryBindParam($bindParam, $name); } }
private function __construct(DirItem $di, $min, $max, $step) { $this->di = $di; $this->min = PsCheck::int($min); $this->max = PsCheck::int($max); $this->step = PsCheck::int($step); //Проверки check_condition($this->max > $this->min, "Некорректные границы [{$this->min}, {$this->max}] для {$this}"); check_condition($this->step > 0, "Некорректный шаг [{$this->step}] для {$this}"); }
/** * Функция, выполняющая закрытие классов. * Должна быть именно public, иначе не будет вызвана! */ static final function _doShotdown() { PsCheck::arr(self::$DESTRUCTS); ksort(self::$DESTRUCTS); /* @var $inst Destructable */ foreach (self::$DESTRUCTS as $ord => $inst) { //Пишем в логгер до закрытия класса, так как логгер закрывается последним PsLogger::inst(__CLASS__)->info($ord . '. ' . get_class($inst) . ' - desctucted'); $inst->onDestruct(); } self::$DESTRUCTS = null; }
/** * В конструкторе проинициализируем все параметры соединения */ private function __construct(array $params, $sourceDescr) { foreach (PsUtil::getClassConsts(__CLASS__, 'PARAM_') as $param) { $value = array_get_value(PsCheck::notEmptyString($param), $params); if (PsCheck::isNotEmptyString($value)) { $this->PARAMS[$param] = $value; } else { $this->PARAMS[$param] = null; //raise_error("Задано пустое значения для параметра $param в источнике $sourceDescr"); } } $this->url = PsStrings::replaceWithBraced("{}://{}:{}@{}/{}", $this->scheme(), $this->user(), $this->password(), $this->host(), $this->database()); $this->toString = PsStrings::replaceWithBraced("{}://{}:{}@{}/{} (source: {})", $this->scheme(), $this->user(), '***', $this->host(), $this->database(), $sourceDescr); }
public function processImpl(PostArrayAdapter $paa, $button) { $login = $paa->str(FORM_PARAM_LOGIN); if (!$login) { return 'Укажите e-mail'; } if (!PsCheck::isEmail($login)) { return 'E-mail должен быть корректным'; } $password = $paa->str(FORM_PARAM_PASS); if (!$password) { return 'Нужно указать пароль'; } return new AdminLoginFormData($login, $password); }
protected function processImpl(PostArrayAdapter $adapter, $button) { $login = $adapter->str(FORM_PARAM_LOGIN); if (!$login) { return array(FORM_PARAM_LOGIN, 'required'); } if (!PsCheck::isEmail($login)) { return array(FORM_PARAM_LOGIN, 'email'); } $password = $adapter->str(FORM_PARAM_PASS); if (!$password) { return array(FORM_PARAM_PASS, 'required'); } $loggedIn = AuthManager::loginUser($login, $password); return $loggedIn ? new AjaxSuccess() : 'В доступе отказано'; }
public static function validateEmail($mail, $mustPresent = false) { if (!$mail) { return 'required'; } if (ps_strlen($mail) > EMAIL_MAXLEN) { return 'maxlength'; } if (!PsCheck::isEmail($mail)) { return 'email'; } $hasMail = UserBean::inst()->hasMail($mail); if ($hasMail && !$mustPresent || !$hasMail && $mustPresent) { return 'remote'; } return false; }
/** * Метод проверяет значение на наличие в ней нецензурной лексики * * * * @param string $string - строка, которая должна быть проверена * @return bool - если есть нецензурные элементы, вернёт строку, в которой эта часть выделена */ public static function parse($string) { /* * Пустая строка или не строка? Возвращаем как есть. */ if (!PsCheck::isNotEmptyString($string)) { return false; //--- } /* * Подключим библиотеку, если нужно */ PsLibs::inst()->Censure(); /* * Обрабатываем */ return Text_Censure::parse($string, '2', "…", false); }
/** * Создание пользователя * @return int userId - код нового пользователя */ public final function createUser(RegFormData $data) { $email = PsCheck::email($data->getUserMail()); //Проверим, что пользователь с таким email ещё не заведён check_condition(!$this->hasMail($email), "Пользователь с почтой [{$email}] уже зарегистрирован"); //Подготовим поля для вставки $params[self::FIELD_NAME] = $data->getUserName(); $params[self::FIELD_SEX] = $data->getSex(); $params[self::FIELD_EMAIL] = $email; $params[self::FIELD_PASSWD] = self::hashPassword($data->getPassword()); $params[self::FIELD_B_ADMIN] = 0; $params[self::FIELD_B_CAN_LOGIN] = 1; $params[] = Query::assocParam(self::FIELD_DT_REG, 'UNIX_TIMESTAMP()', false); //Выполняем вставку $userId = $this->register($this->insert(Query::insert('users', $params))); //Сохраним данные пользователя в аудит UserAudit::inst()->afterRegistered($userId, array_filter_keys($this->getUserDataById($userId), self::$SKIP_AUDIT_ON_CREATE_FIELDS)); //Возвращаем код пользователя return $userId; }
/** * Метод выполняет фактическое получение лока */ private function doLock($lockname, $wait) { PsCheck::notEmptyString($lockname); if ($this->lockName == $lockname) { $this->lockCnt++; $this->LOGGER->info('Lock ident [{}] counter inreased to {}.', $lockname, $this->lockCnt); return true; } check_condition($lockname, 'Lock ident cannot be empty'); check_condition(!$this->lockName, "Lock [{$lockname}] cannot be set, previous lock [{$this->lockName}] is active"); $filename = md5($lockname); $this->LOGGER->info("Trying to get lock with ident [{$lockname}], mode: {}. Lock file name=[{$filename}].", $wait ? 'WAIT' : 'NOWAIT'); /** * Храним в auto-no-del, а не в autogen, так как можем потерять локи при удалении autogen * или вообще не иметь возможности удалить папку autogen. */ $di = DirManager::autoNoDel('locks')->getDirItem(null, $filename, 'lock'); /* * Файл будет создан при открытии */ $fp = fopen($di->getAbsPath(), 'a+'); do { $this->LOGGER->info('Locking file...'); if (flock($fp, $wait ? LOCK_EX : LOCK_EX | LOCK_NB)) { $this->lockCnt = 1; $this->lockFile = $fp; $this->lockName = $lockname; $this->LOGGER->info('Lock acquired!'); return true; } //Мы не получили блокировку... if ($wait) { $this->LOGGER->info('Lock not acquired, sleep for 1 sec'); sleep(1); } } while ($wait); @fclose($fp); $this->LOGGER->info("Lock not setted.\n"); return false; }
function __construct($table, $where = null) { $this->table = PsCheck::tableName($table); $this->addWhere($where); }
/** * Метод возвращает экземпляр класса-плагина Smarty. * Для переопределения этого класса, на уровне проектного config.ini * должен быть задан другой класс. * * Это позволит использовать стандартизованный метод подключения плагинов */ public static final function inst() { if (isset(self::$inst)) { return self::$inst; //---- } /* * Получим название класса */ $class = ConfigIni::smartyPlugin(); /* * Класс подключения библиотек совпадает с базовым */ if (__CLASS__ == $class) { return self::$inst = new PSSmartyPlugin(); } /* * Нам передан класс, который отличается от SDK */ $classPath = Autoload::inst()->getClassPath($class); if (!PsCheck::isNotEmptyString($classPath)) { return PsUtil::raise('Не удалось найти класс плагинов Smarty [{}]', $class); } /* * Указанный класс должен быть наследником данного */ if (!PsUtil::isInstanceOf($class, __CLASS__)) { return PsUtil::raise('Указанный плагин Smarty [{}] не является наследником класса [{}]', $class, __CLASS__); } return self::$inst = new $class(); }
/** * Метод добавляет хешированные директории к пути * * @param type $dirs - директории "перед" хешированными директориями * @param type $hashBase - база для хеша. Если это md5, то он и будет использован для построения пути. * @return array - массив директорий, составляющих путь к папке */ private function addHashFolders($dirs = null, $hashBase = null) { $hash = PsCheck::isMd5($hashBase) ? $hashBase : md5($hashBase ? $hashBase : PsRand::string()); $dirs = to_array($dirs); $dirs[] = 'f' . $hash[0]; $dirs[] = 'f' . $hash[1]; $dirs[] = 'f' . $hash[2]; return $dirs; }
/** * Загрузка конкретной настройки с проверкой её типа */ public static function getPropCheckType($group, $prop, array $allowedTypes = null, $scope = ENTITY_SCOPE_ALL) { return PsCheck::phpVarType(self::getPropOrNull($group, $prop, $scope), $allowedTypes); }
/** * Извлекает тип и подтип фолдинга из его идентификатора: * [lib-p] => [lib, p] */ public static function extractFoldedTypeAndSubtype($foldedUnique, &$type, &$subtype) { $tokens = explode('-', PsCheck::notEmptyString($foldedUnique), 3); $tokensCnt = count($tokens); switch ($tokensCnt) { case 1: $type = PsCheck::notEmptyString($tokens[0]); $subtype = ''; break; case 2: $type = PsCheck::notEmptyString($tokens[0]); $subtype = PsCheck::notEmptyString($tokens[1]); break; default: PsUtil::raise('Invalid folded resource ident: [{}]', $foldedUnique); } }
/** * Определим функцию, которая выполнит все действия - не будем лишними переменными засорять глобальное пространство */ function psExecuteAjaxAction() { /* * Название действия должно быть в переменной запроса. Оно же - название класса, который будет выполнен. * Группа действия должны быть не обязательна, при определении действия группа нужна обязательно. */ $actionName = RequestArrayAdapter::inst()->str(AJAX_ACTION_PARAM); $actionGroup = RequestArrayAdapter::inst()->str(AJAX_ACTION_GROUP_PARAM, 'client'); if (!PsCheck::notEmptyString($actionName) || !PsCheck::notEmptyString($actionGroup)) { return json_error('Не передан код действия или его группа'); //--- } /* * Экземпляр класса действия - должен быть наследником AbstractAjaxAction */ $action = null; /* * Поищем в проектных действиях, они для нас имеют больший приоритет */ foreach (ConfigIni::ajaxActionsAbs($actionGroup) as $dirAbsPath) { $classPath = file_path($dirAbsPath, $actionName, PsConst::EXT_PHP); if (is_file($classPath)) { /* * Нашли файл. Загрузим и проверим, является ли он наследником AbstractAjaxAction */ require_once $classPath; if (!PsUtil::isInstanceOf($actionName, AbstractAjaxAction::getClassName())) { continue; //--- } $action = new $actionName(); break; //--- } } /* * Проверим, существует ли действие. * Для безопасности не будем писать детали обработки. */ if (!$action || !$action instanceof AbstractAjaxAction) { return json_error('Действие не опеределено'); //--- } /* * Выполняем */ $result = null; try { $result = $action->execute(); } catch (Exception $e) { $result = $e->getMessage(); } /* * Проверим результат */ if ($result instanceof AjaxSuccess) { json_success($result->getJsParams()); } else { json_error($result ? $result : 'Ошибка выполнения действия'); } }
public function __construct($group) { $this->group = PsCheck::notEmptyString($group); }
/** * Метод утверждает, что передан валидный хэш формулы */ public static function assertValidFormulaHash($hash) { check_condition(PsCheck::isMd5($hash), "Invalid formula hash: [{$hash}]."); }
/** * Метод возвращает формы слова во всех падежах * * @param type $word * @return array - все склонения слова в виде массива, где под индексом 0 - оригинальное значение */ public function getInflections($word) { $word = PsCheck::notEmptyString(trim($word)); if ($this->CACHE->has($word)) { return $this->CACHE->get($word); } $this->LOGGER->info(); $this->LOGGER->info('> Запрошено склонение для слова [{}]', $word); //$fileName = iconv('UTF-8', 'cp1251', $word); /* * Ищем в БД */ $inflections = InflectsBean::inst()->getInflections($word); if (is_array($inflections)) { $this->LOGGER->info('< Cклонение для [{}] найдено в базе: {}', $word, array_to_string($inflections)); return $this->CACHE->set($word, $inflections); } /* * Загружаем с сервиса */ $inflections = $this->loadInflectionImpl($word); if (is_array($inflections) && count($inflections) == 7) { $this->LOGGER->info('< Склонение для [{}] успешно загружено: {}', $word, array_to_string($inflections)); //Не забудем сохранить полеченное склонение для слова InflectsBean::inst()->saveInflections($inflections); return $this->CACHE->set($word, $inflections); } /* * Загрузить не удалось, возвращаем балванку */ $inflections = array_fill(0, 7, $word); $this->LOGGER->info('< Склонение для [{}] не определено, возвращаем "болванку": {}', $word, array_to_string($inflections)); return $this->CACHE->set($word, $inflections); }
/** @return QueryParamPlain */ public function addBindParam($param) { $this->bindParams[] = PsCheck::queryBindParam($param, $this->expression); return $this; }
public static function setInt($key, $int) { $_SESSION[$key] = PsCheck::int($int); }
/** * Метод возвращает экземпляр класса-хранилища экземпляров фолдинов. * Для переопределения этого класса, на уровне проектного config.ini * должен быть задан другой класс. * * @return FoldedStorageInsts */ protected static final function inst() { if (isset(self::$inst)) { return self::$inst; //---- } /* * Получим название класса */ $class = FoldingsIni::foldingsStore(); /* * Класс совпадает с базовым */ if (__CLASS__ == $class) { return self::$inst = new FoldedStorageInsts(); } /* * Нам передан класс, который отличается от SDK */ $classPath = Autoload::inst()->getClassPath($class); if (!PsCheck::isNotEmptyString($classPath)) { return PsUtil::raise('Не удалось найти класс регистрации экземпляров фолдингов [{}]', $class); } /* * Указанный класс должен быть наследником данного */ if (!PsUtil::isInstanceOf($class, __CLASS__)) { return PsUtil::raise('Указанный класс регистрации экземпляров фолдингов [{}] не является наследником класса [{}]', $class, __CLASS__); } return self::$inst = new $class(); }
/** * Метод возвращает экземпляр класса, подключающего библиотеки. * Для переопределения этого класса, на уровне проектного config.ini * должен быть задан другой класс, отвечающий за подключение библиотек. * * Это позволит: * 1. Использовать стандартизованный метод подключения внешних библиотек * 2. Переопределить подключение библиотек из SDK */ public static final function inst() { if (isset(self::$inst)) { return self::$inst; //---- } /* * Получим название класса, отвечающего за подключение библиотек */ $class = ConfigIni::libsIncluder(); /* * Подготовим директории */ $SDK_LIB_DIR = DirManager::inst(PS_DIR_INCLUDES, DirManager::DIR_LIB)->absDirPath(); $PROJ_LIB_DIR = DirManager::inst(PS_DIR_ADDON, DirManager::DIR_LIB)->absDirPath(); /* * Класс подключения библиотек совпадает с базовым */ if (__CLASS__ == $class) { self::$inst = new PsLibs(); self::$inst->SDK_LIB_DIR = $SDK_LIB_DIR; self::$inst->LOGGER = PsLogger::inst($class); self::$inst->LOGGER->info('Libs includer SDK: [{}]', __FILE__); self::$inst->LOGGER->info('Libs directory SDK: [{}]', $SDK_LIB_DIR); return self::$inst; //--- } /* * Нам передан класс, который отличается от SDK */ $classPath = Autoload::inst()->getClassPath($class); if (!PsCheck::isNotEmptyString($classPath)) { return PsUtil::raise('Не удалось найти класс загрузчика библиотек [{}]', $class); } /* * Указанный класс должен быть наследником данного */ if (!PsUtil::isInstanceOf($class, __CLASS__)) { return PsUtil::raise('Указанный загрузчик библиотек [{}] не является наследником класса [{}]', $class, __CLASS__); } self::$inst = new $class(); self::$inst->SDK_LIB_DIR = $SDK_LIB_DIR; self::$inst->PROJ_LIB_DIR = $PROJ_LIB_DIR; self::$inst->LOGGER = PsLogger::inst($class); self::$inst->LOGGER->info('Libs includer CUSTOM: [{}]', $classPath); self::$inst->LOGGER->info('Libs directory SDK: [{}]', $SDK_LIB_DIR); self::$inst->LOGGER->info('Libs directory CUSTOM: [{}]', $PROJ_LIB_DIR); return self::$inst; //--- }
public function isRubricable() { return PsCheck::isNotEmptyString($this->rubricsTable); }
private static function assertValidType($type) { return PsCheck::notEmptyString($type); }