/** * Returns the mapped source for a model * * @param \ManaPHP\Mvc\ModelInterface|string $model * * @return string */ public function getModelSource($model) { $modelName = is_string($model) ? $model : get_class($model); if (!isset($this->_sources[$modelName])) { if ($this->_recallGetModelSource) { return Text::underscore(Text::contains($modelName, '\\') ? substr($modelName, strrpos($modelName, '\\') + 1) : $modelName); } $modelInstance = is_string($model) ? new $model() : $model; /** @noinspection NotOptimalIfConditionsInspection */ if (!isset($this->_sources[$modelName])) { $this->_recallGetModelSource = true; $this->_sources[$modelName] = $modelInstance->getSource(); $this->_recallGetModelSource = false; } } return $this->_sources[$modelName]; }
/** * @param string $key * * @return string */ protected function _getFileName($key) { if ($key[0] === '!') { return $this->alias->resolve($this->_dir . '/' . str_replace(':', '/', substr($key, 1)) . $this->_extension); } if (Text::contains($key, '/')) { $parts = explode('/', $key, 2); $md5 = $parts[1]; $file = $this->_dir . '/' . $parts[0] . '/'; for ($i = 0; $i < $this->_level; $i++) { $file .= substr($md5, $i + $i, 2) . '/'; } $file .= $md5; } else { $file = $this->_dir . '/' . $key; } return $this->alias->resolve(str_replace(':', '/', $file . $this->_extension)); }
/** * @description minify the ManaPHP framework source code * @return int */ public function defaultCommand() { $ManaPHPSrcDir = $this->alias->get('@manaphp'); $ManaPHPDstDir = $ManaPHPSrcDir . '_' . date('ymd'); $totalClassLines = 0; $totalInterfaceLines = 0; $totalLines = 0; $fileLines = []; $sourceFiles = $this->_getSourceFiles($ManaPHPSrcDir); foreach ($sourceFiles as $file) { $dstFile = str_replace($ManaPHPSrcDir, $ManaPHPDstDir, $file); $content = $this->_minify($this->filesystem->fileGet($file)); $lineCount = Text::contains($content, "\r") ? substr_count($content, "\r") : substr_count($content, "\n"); if (Text::contains($file, 'Interface.php')) { $totalInterfaceLines += $lineCount; $totalLines += $lineCount; } else { $totalClassLines += $lineCount; $totalLines += $lineCount; } $this->console->writeLn($content); $this->filesystem->filePut($dstFile, $content); $fileLines[$file] = $lineCount; } asort($fileLines); $i = 1; $this->console->writeLn('------------------------------------------------------'); foreach ($fileLines as $file => $line) { $this->console->writeLn(sprintf('%3d %3d %.3f', $i++, $line, $line / $totalLines * 100) . ' ' . substr($file, strpos($file, 'ManaPHP'))); } $this->console->writeLn('------------------------------------------------------'); $this->console->writeLn('total lines: ' . $totalLines); $this->console->writeLn('class lines: ' . $totalClassLines); $this->console->writeLn('interface lines: ' . $totalInterfaceLines); return 0; }
/** * @param string|array $uri * @param array $args * @param string $module * * @return string * @throws \ManaPHP\Mvc\Url\Exception */ public function get($uri, $args = [], $module = null) { if (is_array($uri)) { $tmp = $uri; $uri = $tmp[0]; if (isset($tmp[1])) { $args = $tmp[1]; } if (isset($tmp[2])) { $module = $tmp[2]; } } /** @noinspection CallableParameterUseCaseInTypeContextInspection */ if (is_string($args)) { $module = $args; $args = []; } if (!isset($this->_baseUrls[$module])) { if (isset($this->_baseUrls[ucfirst($module)])) { throw new UrlException('module name is case-sensitive: `:module`', ['module' => $module]); } else { throw new UrlException('`:module` is not exists', ['module' => $module]); } } if ($uri === '' || $uri[0] !== '/') { $baseUrl = $this->_baseUrls[$module]; $strUrl = (strpos($baseUrl, '://') ? parse_url($baseUrl, PHP_URL_PATH) : $baseUrl) . '/' . $uri; } else { $strUrl = $this->_baseUrls[$module] . $uri; } if (Text::contains($strUrl, ':')) { foreach ($args as $k => $v) { $count = 0; $strUrl = str_replace(':' . $k, $v, $strUrl, $count); if ($count !== 0) { unset($args[$k]); } } } if (count($args) !== 0) { $strUrl .= (Text::contains($strUrl, '?') ? '&' : '?') . http_build_query($args); } return $strUrl; }
/** * @param string|array $url * * @return string */ protected function _buildUrl($url) { if (is_string($url)) { return $url; } return $url[0] . (Text::contains($url[0], '?') ? '&' : '?') . http_build_query($url[1]); }
/** * @param string $level * @param string $message * @param array $context * * @return static */ public function log($level, $message, $context) { $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); $location = ''; if (isset($traces[1])) { $trace = $traces[1]; if (isset($trace['file'], $trace['line'])) { $location = str_replace($this->alias->get('@app'), '', str_replace('\\', '/', $trace['file'])) . ':' . $trace['line']; } } if (Text::contains($message, '%')) { $replaces = []; foreach ($context as $k => $v) { $replaces['%' . $k . '%'] = $v; } $message = strtr($message, $replaces); } $context['level'] = $level; $context['date'] = time(); $context['location'] = $location; $eventData = ['level' => $level, 'message' => $message, 'context' => $context]; $this->fireEvent('logger:log', $eventData); if ($this->_s2i[$level] > $this->_s2i[$this->_level]) { return $this; } $this->adapter->log($level, $message, $context); return $this; }
/** * @param string $uri * * @return bool|array * @throws \ManaPHP\Mvc\Router\Route\Exception */ public function match($uri) { $matches = []; if ($this->_httpMethod !== null && $this->_httpMethod !== $_SERVER['REQUEST_METHOD']) { return false; } if (Text::contains($this->_compiledPattern, '^')) { $r = preg_match($this->_compiledPattern, $uri, $matches); if ($r === false) { throw new RouteException('`:compiled` pcre pattern is invalid for `:pattern`', ['compiled' => $this->_compiledPattern, 'pattern' => $this->_pattern]); } elseif ($r === 1) { return $matches; } else { return false; } } else { if ($this->_compiledPattern === $uri) { return $matches; } else { return false; } } }
/** * @param string $attachmentName * * @return static */ public function setAttachment($attachmentName) { if (isset($_SERVER['HTTP_USER_AGENT'])) { $userAgent = $_SERVER['HTTP_USER_AGENT']; if (Text::contains($userAgent, 'Trident') || Text::contains($userAgent, 'MSIE')) { $attachmentName = urlencode($attachmentName); } } $this->setHeader('Content-Description', 'File Transfer'); $this->setHeader('Content-Type', 'application/octet-stream'); $this->setHeader('Content-Disposition', 'attachment; filename=' . $attachmentName); $this->setHeader('Content-Transfer-Encoding', 'binary'); $this->setHeader('Cache-Control', 'must-revalidate'); return $this; }
/** * Returns a SQL statement built based on the builder parameters * * @return string * @throws \ManaPHP\Mvc\Model\QueryBuilder\Exception */ protected function _buildSql() { if (count($this->_union) !== 0) { return $this->_getUnionSql(); } if (count($this->_models) === 0) { throw new QueryBuilderException('at least one model is required to build the query'); } $sql = 'SELECT '; if ($this->_distinct) { $sql .= 'DISTINCT '; } if ($this->_columns !== null) { $columns = $this->_columns; } else { $columns = ''; $selectedColumns = []; /** @noinspection ForeachSourceInspection */ foreach ($this->_models as $alias => $model) { $selectedColumns[] = '[' . (is_int($alias) ? $model : $alias) . '].*'; } $columns .= implode(', ', $selectedColumns); } $sql .= $columns; $selectedModels = []; /** @noinspection ForeachSourceInspection */ foreach ($this->_models as $alias => $model) { if ($model instanceof $this) { if (is_int($alias)) { throw new QueryBuilderException('if using SubQuery, you must assign an alias for it'); } $selectedModels[] = '(' . $model->getSql() . ') AS [' . $alias . ']'; /** @noinspection SlowArrayOperationsInLoopInspection */ $this->_bind = array_merge($this->_bind, $model->getBind()); } else { if (is_string($alias)) { $selectedModels[] = '[' . $model . '] AS [' . $alias . ']'; } else { $selectedModels[] = '[' . $model . ']'; } } } $sql .= ' FROM ' . implode(', ', $selectedModels); $joinSQL = ''; /** @noinspection ForeachSourceInspection */ foreach ($this->_joins as $join) { $joinModel = $join[0]; /** @noinspection MultiAssignmentUsageInspection */ $joinCondition = $join[1]; /** @noinspection MultiAssignmentUsageInspection */ $joinAlias = $join[2]; /** @noinspection MultiAssignmentUsageInspection */ $joinType = $join[3]; if ($joinAlias !== null) { $this->_models[$joinAlias] = $joinModel; } else { $this->_models[] = $joinModel; } if ($joinType !== null) { $joinSQL .= ' ' . $joinType; } if ($joinModel instanceof $this) { $joinSQL .= ' JOIN (' . $joinModel->getSql() . ')'; /** @noinspection SlowArrayOperationsInLoopInspection */ $this->_bind = array_merge($this->_bind, $joinModel->getBind()); if ($joinAlias === null) { throw new QueryBuilderException('if using SubQuery, you must assign an alias for it'); } } else { $joinSQL .= ' JOIN [' . $joinModel . ']'; } if ($joinAlias !== null) { $joinSQL .= ' AS [' . $joinAlias . ']'; } if ($joinCondition) { $joinSQL .= ' ON ' . $joinCondition; } } $sql .= $joinSQL; $wheres = []; if (is_string($this->_conditions)) { $this->_conditions = [$this->_conditions]; } /** @noinspection ForeachSourceInspection */ foreach ($this->_conditions as $k => $v) { if ($v === '') { continue; } if (is_int($k)) { $wheres[] = Text::contains($v, ' or ', true) ? "({$v})" : $v; } else { $wheres[] = "[{$k}]=:{$k}"; $this->_bind[$k] = $v; } } if (count($wheres) !== 0) { $sql .= ' WHERE ' . implode(' AND ', $wheres); } if ($this->_group !== null) { $sql .= ' GROUP BY ' . $this->_group; } if ($this->_having !== null) { $sql .= ' HAVING ' . $this->_having; } if ($this->_order !== null) { $sql .= ' ORDER BY ' . $this->_order; } if ($this->_limit !== 0) { $sql .= ' LIMIT ' . $this->_limit; } if ($this->_offset !== 0) { $sql .= ' OFFSET ' . $this->_offset; } if ($this->_forUpdate) { $sql .= ' FOR UPDATE'; } //compatible with other SQL syntax $replaces = []; foreach ($this->_bind as $key => $_) { $replaces[':' . $key . ':'] = ':' . $key; } $sql = strtr($sql, $replaces); /** @noinspection ForeachSourceInspection */ foreach ($this->_models as $model) { if (!$model instanceof $this) { $sql = str_replace('[' . $model . ']', '[' . $this->modelsManager->getModelSource($model) . ']', $sql); } } return $sql; }
/** * Deletes data from a table using custom SQL syntax * <code> * //Deleting existing robot * $success = $connection->delete( * "robots", * "id = 101" * ); * //Next SQL sentence is generated * DELETE FROM `robots` WHERE `id` = 101 * </code> * * @param string $table * @param string|array $conditions * @param array $bind * * @return int * @throws \ManaPHP\Db\Exception */ public function delete($table, $conditions, $bind = []) { if (is_string($conditions)) { $conditions = [$conditions]; } $wheres = []; /** @noinspection ForeachSourceInspection */ foreach ($conditions as $k => $v) { if (is_int($k)) { $wheres[] = Text::contains($v, ' or ', true) ? "({$v})" : $v; } else { $wheres[] = "`{$k}`=:{$k}"; $bind[$k] = $v; } } $sql = "DELETE FROM `{$table}` WHERE " . implode(' AND ', $wheres); return $this->execute($sql, $bind); }
/** * Moves the temporary file to a destination within the application * * @param string $dst * @param string|false $allowedExtensions * * @throws \ManaPHP\Filesystem\Adapter\Exception * @throws \ManaPHP\Http\Request\File\Exception */ public function moveTo($dst, $allowedExtensions = 'jpg,jpeg,png,gif,doc,xls,pdf,zip') { $extension = pathinfo($dst, PATHINFO_EXTENSION); if ($extension) { $extension = ',' . $extension . ','; if (is_string($allowedExtensions)) { $allowedExtensions = ',' . str_replace(' ', '', $allowedExtensions) . ','; $allowedExtensions = str_replace(',.', ',', $allowedExtensions); if (!Text::contains($allowedExtensions, $extension, true)) { throw new FileException('`:extension` file type is not allowed upload', ['extension' => $extension]); } } if (is_string(self::$_alwaysRejectedExtensions)) { $alwaysRejectedExtensions = ',' . str_replace(' ', '', self::$_alwaysRejectedExtensions) . ','; $alwaysRejectedExtensions = str_replace(',.', ',', $alwaysRejectedExtensions); if (Text::contains($alwaysRejectedExtensions, $extension, true)) { throw new FileException('`:extension` file types is not allowed upload always', ['extensions' => self::$_alwaysRejectedExtensions]); } } } if ($this->_file['error'] !== UPLOAD_ERR_OK) { throw new FileException('error code of upload file is not UPLOAD_ERR_OK: :error', ['error' => $this->_file['error']]); } if ($this->filesystem->fileExists($dst)) { throw new FileException('`:file` file already exists', ['file' => $dst]); } $this->filesystem->dirCreate(dirname($dst)); if (!move_uploaded_file($this->_file['tmp_name'], $this->alias->resolve($dst))) { throw new FileException('move_uploaded_file to `:dst` failed: :last_error_message', ['dst' => $dst]); } if (!chmod($this->alias->resolve($dst), 0644)) { throw new FileException('chmod `:dst` destination failed: :last_error_message', ['dst' => $dst]); } }
/** * Renders a partial view * * <code> * //Show a partial inside another view * $this->partial('shared/footer'); * </code> * * <code> * //Show a partial inside another view with parameters * $this->partial('shared/footer', array('content' => $html)); * </code> * * @param string $path * @param array $vars * * @throws \ManaPHP\Mvc\View\Exception * @throws \ManaPHP\Renderer\Exception */ public function partial($path, $vars = []) { if (!Text::contains($path, '/')) { $path = $this->_controllerName . '/' . $path; } $this->_render("@views/{$path}", $vars, true); }
/** * @param string $attribute * @param string $filter * @param array $parameters * @param mixed $value * * @return mixed * @throws \ManaPHP\Http\Filter\Exception */ protected function _sanitize($attribute, $filter, $parameters, $value) { $srcValue = $value; if (isset($this->_filters[$filter])) { $value = call_user_func_array($this->_filters[$filter], [$value, $parameters]); } elseif (function_exists($filter)) { $value = call_user_func_array($filter, array_merge([$value], $parameters)); } else { throw new FilterException('`:name` filter is not be recognized', ['name' => $filter]); } if ($value === null) { if (is_string($this->_messages)) { if (!Text::contains($this->_messages, '.')) { $file = '@manaphp/Http/Filter/Messages/' . $this->_messages . '.php'; } else { $file = $this->_messages; } if (!$this->filesystem->fileExists($file)) { throw new FilterException('`:file` filter message template file is not exists', ['file' => $file]); } /** @noinspection PhpIncludeInspection */ $this->_messages = (require $this->alias->resolve($file)); } if (isset($this->_messages[$filter])) { $message = $this->_messages[$filter]; } else { $message = $this->_defaultMessage; } $bind = []; $bind['filter'] = $filter; $bind['attribute'] = isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : $attribute; $bind['value'] = $srcValue; foreach ($parameters as $k => $parameter) { $bind['parameter[' . $k . ']'] = $parameter; } throw new FilterException($message, $bind); } return $value; }
/** * @param string $template * * @return string * @throws \ManaPHP\Debugger\Exception */ public function save($template = 'Default') { if (Text::contains($_SERVER['HTTP_USER_AGENT'], 'ApacheBench')) { return ''; } $file = date('/ymd/His_') . $this->random->getBase(32) . '.html'; $this->filesystem->filePut('@data/debugger' . $file, $this->output($template)); return $this->url->get('/?_debugger=' . $file); }