private function getImages(ArrayAdapter $params, $FNAME) { $dir = $params->str('dir'); $name = $params->get('name'); //НЕПОСРЕДСТВЕННО КАРТИНКА if ($name instanceof DirItem) { return $name; } /* * FOLDING */ $FCW = FoldedContextWatcher::getInstance(); $folding = null; $ident = $params->get('ident'); //Тип фолдинга. Он может быть передан либо в параметре 'group', либо по префиксу смарти-функции, например: postimg (post-название типа фолдинга). $foldingType = $params->get('group'); $foldingType = $foldingType ? $foldingType : (starts_with($FNAME, 'img') ? null : array_get_value(0, explode('img', $FNAME))); //Подтип фолдинга, например: is - подтип фолдингов для фолдингов с типом post (выпуск журнала среди всех постов). $foldingSubType = $params->get('type'); if ($params->has('post')) { /* @var $post AbstractPost */ $post = $params->get('post'); $ident = $post->getIdent(); $folding = Handlers::getInstance()->getPostsProcessorByPostType($post->getPostType())->getFolding(); } else { if ($foldingType) { $hasSubtype = FoldedStorage::isFoldingHasSubtype($foldingType); if ($hasSubtype && !$foldingSubType) { //У фолдинга есть подтип, но в параметрах он не передан - определим фолдинг по контексту $folding = $FCW->getFoldedEntityEnsureType($foldingType)->getFolding(); } else { $folding = FoldedStorageInsts::byTypeStype($foldingType, $foldingSubType); } } else { if ($foldingSubType) { //Если передан только тип, то считаем, что имеется ввиду фолдинг поста $folding = Handlers::getInstance()->getPostsProcessorByPostType($foldingSubType)->getFolding(); } } } if ($folding && !$ident) { //У нас есть фолдинг, но нет идентификатора сущности - определим её из контекста $ident = $FCW->getFoldedEntityEnsureType($folding->getFoldingType())->getIdent(); } if (!$dir && !$name && $ident && $folding) { /* * Не передано название картинки, но передан идентификатор сущности - показываем cover. * TODO - подумать, возможно имеет смысл сделать возможность показывать любую картинку в заданном размере. */ return $folding->getCover($ident, $params->str('dim')); } /* * Берём путь "как есть", если: * 1. Передан специальный параметр asis * 2. Передана dir, и она начинается с '/' * 3. Не передана dir, но при этом name начинается с '/' * 4. dir или name указывают на адрес в интернете */ $asis = $params->bool('asis') || starts_with($dir, DIR_SEPARATOR) || !$dir && starts_with($name, DIR_SEPARATOR) || PsUrl::isHttp($dir) || PsUrl::isHttp($name); if ($asis) { if (!$dir) { return $name; } if (starts_with($name, DIR_SEPARATOR)) { return cut_string_end($dir, DIR_SEPARATOR) . $name; } return ($name ? ensure_ends_with($dir, DIR_SEPARATOR) : $dir) . $name; } /** @var DirManager */ $DM = null; /* * Теперь определим DirManager. Мы его можем взять: */ if ($folding) { //1. Из ресурсов фолдинга $DM = $folding->getResourcesDm($ident, 'src'); } else { //2. Обычный resources->images, если фолдинг не установлен $DM = DirManager::images(); } /* * Определим список показываемых картинок по атрибуту $name. Пример тега: * {postimg type='tr' ident='matrix' name='mao.gif mu.png mu.png'} * Просто разделим значение атрибута $name по точкам и пробелам и склеим в названия картинок. */ $NAMES = preg_split("/[. ]/", $name); $DI = $DM ? $DM->getDirItem($dir, $name) : DirItem::inst($dir, $name); if (count($NAMES) % 2 != 0 || $DI->isImg()) { //Указано что-то непонятное - не чётное кол-во составных элементов return $DI; } $IMAGES = array(); for ($i = 0; $i < count($NAMES); $i += 2) { $imgName = $NAMES[$i] . '.' . $NAMES[$i + 1]; $IMAGES[] = $DM ? $DM->getDirItem($dir, $imgName) : DirItem::inst($dir, $imgName); } return $IMAGES; }
function ensure_wrapped_with($haystack, $start, $end) { return ensure_ends_with(ensure_starts_with($haystack, $start), $end); }
/** @return FileUploader */ public static final function inst($classPrefix = null) { $class = $classPrefix ? ensure_ends_with($classPrefix, 'Uploader') : get_called_class(); check_condition(PsUtil::isInstanceOf($class, __CLASS__), "Class {$class} is not instance of " . __CLASS__); return array_key_exists($class, self::$insts) ? self::$insts[$class] : (self::$insts[$class] = new $class()); }
/** * Метод возвращает список действий, которые должны быть выполнены в рамках триггера. * Под действием понимается вызов процедуры. * * @return null|string */ public static function getTriggerActions($table, $scope, $action) { $result = array(); $TABLE_WITH_CACHE = self::getTablesWithCache($scope == ENTITY_SCOPE_PROJ ? ENTITY_SCOPE_ALL : $scope); $TABLE2FOLDINGS = self::getTables2Foldings($scope == ENTITY_SCOPE_PROJ ? ENTITY_SCOPE_ALL : $scope); if (in_array($table, $TABLE_WITH_CACHE) || array_key_exists($table, $TABLE2FOLDINGS)) { $result[] = "CALL onDbChange('{$table}', '" . DbBean::CHANGE_TABLE . "')"; } if ($action == self::ACTION_UPDATE && array_key_exists($table, $TABLE2FOLDINGS)) { /* @var $folding FoldedResources */ foreach ($TABLE2FOLDINGS[$table] as $folding) { $columnIdent = $folding->getTableColumnIdent(); $columnStype = $folding->getTableColumnStype(); if ($columnStype) { //Если в таблице есть столбец с подтипом фолдинга, то достаточно добавить один триггер $ftype = $folding->getFoldingType(); $result[] = "CALL onDbChange(CONCAT('{$ftype}-', NEW.{$columnStype}, '-', NEW.{$columnIdent}), '" . DbBean::CHANGE_FOLD_ENT . "')"; } else { $unique = $folding->getUnique(); $result[] = "CALL onDbChange(CONCAT('{$unique}-', NEW.{$columnIdent}), '" . DbBean::CHANGE_FOLD_ENT . "')"; } } } /** * Небольшая обработка */ $fetched = array(); foreach ($result as $line) { $fetched[] = "\t" . ensure_ends_with(trim($line), ';'); } /* * Если мы собираем действия для проекта и они совпадают с действиями для SDK - триггер не выкладываем */ if ($scope == ENTITY_SCOPE_PROJ) { $sdkActions = self::getTriggerActions($table, ENTITY_SCOPE_SDK, $action); if (simple_hash($fetched) == simple_hash($sdkActions)) { return null; //--- } } return $fetched; }
/** * Сохраняет значение для вставки его в запрос */ public function safe4insert($val) { if ($this->isFk()) { if (is_string($val) && contains_substring($val, 'select')) { return ensure_ends_with(ensure_starts_with($val, '('), ')'); } return is_numeric($val) ? 1 * $val : null; } switch ($this->getType()) { case self::TYPE_BIT: case self::TYPE_INT: case self::TYPE_INT_DATE: return is_numeric($val) ? 1 * $val : 'null'; case self::TYPE_CHAR: case self::TYPE_STRING: case self::TYPE_STRING_DATE: case self::TYPE_TEXT: //MySQL различает пустую строку и null. Если столбец nullable и значение пустое - вставим null //Обязательно нужно выполнить mysql_real_escape_string, чтобы безопасно вставить значение return $this->isNullable() && !$val ? 'null' : "'" . mysql_real_escape_string($val) . "'"; } }