public function sortRoutes() { if (empty($this->routes)) { if ($files = $this->resolver->getRoutes()) { foreach ($files as $file) { $dir = dirname($file, 2); /** @var Router $router */ $router = (new Injector())->make('Minute\\Routing\\Router'); require_once $file; $routes = $router->getRouteCollection(); /** @var Route $route */ foreach ($routes as $route) { $method = $route->getMethods()[0]; $defaults = $route->getDefaults(); if ($controller = $defaults['controller']) { $parts = explode('@', $controller, 2); list($classPath, $fn) = [$this->utils->unixPath($parts[0]), $parts[1] ?? 'index']; } else { list($classPath, $fn) = [null, 'index']; } $classPath = preg_replace('/\\.php$/', '', $classPath); $path = $this->utils->unixPath(sprintf('%s/Controller/%s.php', $dir, $classPath)); $action = [$this->resolver->getController($classPath), $fn]; $this->routes[] = array_merge($defaults, ['route' => $route, 'controller' => $controller, 'dir' => $dir, 'path' => $path, 'classPath' => $classPath, 'fn' => $fn, 'action' => $action, 'method' => $method]); } } } } return $this->routes; }
public function setContentWithLayout(string $textContent, string $layout = 'Global', array $vars = []) { $this->compiler->setContents($textContent); if ($path = $this->resolver->getView("Layout\\{$layout}")) { $textContent = $this->compiler->compile([$path]); } $this->setVars($vars); $this->setContent($textContent); return $this; }
public function compile(ImportEvent $importEvent) { $results = ['constants' => [], 'handlers' => []]; $wildcards = []; foreach (['constants', 'handlers'] as $type) { $e = $type === 'constants'; foreach (['App', 'Minute'] as $dir) { $prefix = $e ? "{$dir}\\Event\\" : "{$dir}\\EventHandler\\"; $dirs = $this->resolver->find($prefix); if (!empty($dirs)) { $finder = new Finder(); $fix = function ($path, $replacement) use($prefix) { return preg_replace('/\\.php$/', '', preg_replace(sprintf('/^.*%s/i', preg_quote($prefix)), $replacement, $path)); }; $files = $finder->depth('< 3')->files()->in($dirs)->name('*.php')->contains($e ? 'const ' : 'function '); foreach ($files as $file) { $classPath = $this->utils->dosPath((string) $file); $classPath = $fix($classPath, $prefix); $basename = $fix($classPath, ''); if ($reflector = new ReflectionClass($classPath)) { if ($e) { foreach ($reflector->getConstants() as $value => $constant) { $parts = explode('.', $constant); for ($i = 0, $j = count($parts) - 1; $i < $j; $i++) { $wildcard = join('.', array_slice($parts, 0, $i + 1)) . '.*'; $wildcards[$wildcard] = ['name' => sprintf('%s', strtr($wildcard, '.', '_')), 'value' => $wildcard, 'group' => 'Wildcard events']; } $results['constants'][] = ['name' => sprintf('%s in %s', $this->utils->filename($value), $basename), 'value' => $constant, 'group' => $parts[0]]; } } else { foreach ($reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { if (!preg_match('/^\\_/', $method->name)) { $value = sprintf("%s@%s", $method->class, $method->name); $parts = explode('\\', $classPath); $results['handlers'][] = ['name' => sprintf('%s@%s', $basename, $method->name), 'value' => $value, 'group' => $parts[2] ?? 'App']; } } } } } } } usort($results[$type], function ($a, $b) { return $a['group'] === $b['group'] ? $a['value'] <=> $b['value'] : $a['group'] <=> $b['group']; }); } usort($wildcards, function ($a, $b) { return $a['value'] <=> $b['value']; }); foreach ($wildcards as $wildcard => $event) { $results['constants'][] = $event; } $importEvent->addContent($results); }
public function getUserGroups($userId, $extended = false) { $results = $this->cache->get("user-groups-{$userId}-{$extended}", function () use($userId, $extended) { if ($userGroupModel = $this->resolver->getModel('UserGroup', true)) { $groups = $userGroupModel::where('user_id', '=', $userId)->get(); /** @var ModelEx $group */ foreach ($groups as $group) { $results[] = $extended ? $group->getAttributes() : $group->group_name; } } return $results ?? []; }, 3600); return $results ?? []; }
public function write() { $pdo = $this->database->getConnection(); $tables = $pdo->select(sprintf("SELECT TABLE_NAME as `table`, COLUMN_NAME as pk FROM information_schema.columns WHERE table_schema = '%s' AND COLUMN_KEY = 'PRI'", $pdo->getDatabaseName())); foreach ($tables as $table) { $name = $table->table; if (!$this->resolver->getModel($name)) { $path = sprintf('%s/app/Model/%s.php', $this->bootLoader->getBaseDir(), ucfirst(Str::camel(Str::singular("{$name}")))); if (!file_exists($path)) { $this->writer->write($path, ['class' => $this->utils->filename($path), 'table' => $table->table, 'pk' => $table->pk], 'Created new model'); } } } }
public function modelToJsClasses($parent, string $foreignKey = '') { /** @var ModelEx $model */ $self = $parent['self']; $template = ''; if ($class = $this->resolver->getModel($self['name'])) { $model = new $class(); $localKey = $model->getKeyName(); $template .= $this->modelJs->createItem($self['alias'], $parent['children'], $this->database->getColumns($model->getTable())); $template .= $this->modelJs->createItemArray($self['alias'], $class, $localKey, $foreignKey); foreach ($parent['children'] ?? [] as $child) { $template .= $this->modelToJsClasses($child, $localKey); } } return $template; }
/** * @param string $viewFile * @param bool $withLayout * @param bool $useCache * * @return ViewParser * @throws ViewError */ public function loadViewFile(string $viewFile, bool $withLayout = true, bool $useCache = true) { $compiler = function () use($viewFile, $withLayout) { if ($files[] = $path = $this->resolver->getView($viewFile)) { if ($withLayout === true) { for ($i = 0, $layout = dirname($viewFile); $i <= 10 && $layout !== '.'; $layout = dirname($layout), $i++) { $includes[] = $layout; } $includes = array_merge($includes ?? [], ['Global']); } if ($additionalLayouts = $this->getAdditionalLayoutFiles()) { $includes = array_merge($includes ?? [], $additionalLayouts); } if (!empty($includes)) { $files = array_merge($files, array_filter(array_map(function ($l) { return $this->resolver->getView("Layout\\{$l}"); }, $includes))); } $compiled = $this->compiler->compile($files); return $compiled; } else { throw new ViewError("Unable to find view file: {$viewFile}"); } }; $this->content = $useCache ? $this->cache->get("compiled:{$viewFile}", $compiler, self::CACHE_TIMEOUT) : $compiler(); return $this; }
/** * Bind listeners defined in plugins, app and Database */ public function bind() { $listeners = $this->cache->get('app-listeners', function () { foreach ($this->resolver->getListeners() as $file) { try { $binding = $this; require_once $file; } catch (\Throwable $e) { $this->logger->warn("Unable to include {$file}: " . $e->getMessage()); } } $listeners = $this->getListeners(); if ($this->database->isConnected()) { /** @var ModelEx $eventModel */ if ($eventModel = $this->resolver->getModel('Event', true)) { try { foreach ($eventModel::all() as $item) { $attrs = $item->attributesToArray(); list($class, $func) = @explode('@', $attrs['handler']); $event = array_merge($attrs, ['event' => $attrs['name'], 'handler' => [sprintf('\\%s', ltrim($class, '\\')), $func ?? 'index']]); $listeners[] = $event; } } catch (\Exception $e) { } } } return $listeners; }, 300); foreach ($listeners as $listener) { $this->dispatcher->listen($listener['event'], $listener['handler'], $listener['priority'] ?? 99, $listener['data'] ?? ''); } }
private function findParentByAlias($_parents, $child) { foreach ($_parents as $parent) { if ($parent['alias'] === $child) { return $parent; } } return $this->resolver->getModel($child) ? ['name' => $child, 'alias' => $child] : false; }
/** * @param $controller * * @return mixed */ protected function getController($controller) { if ($controller instanceof Closure) { return $controller; } elseif (is_string($controller)) { @(list($class, $function) = explode('@', $controller, 2)); return [$this->resolver->getController($class), $function ?? 'index']; } return $controller; }
/** * Find all route.php files and add them to route collection */ public function compile() { if ($files = $this->resolver->getRoutes()) { /** @noinspection PhpUnusedLocalVariableInspection - is accessed in routes.php file */ $router = $this; foreach ($files as $file) { require_once $file; } } return $this; }
/** * @param array $node * @param ModelEx $parent * * @return mixed * @throws ModelError */ public function createRelations($node, $parent = null) { $self = $node['self']; $class = $this->resolver->getModel($self['name']); $defaults = $this->getDefaults($self); try { $model = new $class(); } catch (\Throwable $e) { throw new ModelError("{$self['name']} table or model class not found."); } if ($parent) { $parent::addRelation($self['single'] ? 'hasOne' : 'hasMany', $self['alias'], get_class($model), $self['matchInfo']['column'] ?? $self['matchInfo']['key'], $self['matchInfo']['key'], $defaults, $node); } else { $model = $this->modelExtender->extend($model, $defaults, $node); } foreach ($node['children'] ?? [] as $child) { $this->createRelations($child, $class); } return $model; }
public function index(RouteEx $_route) { $folders = $this->resolver->find('App\\Controller\\Cron'); $controllers = []; foreach ($folders as $folder) { $classes = glob("{$folder}/*.php"); foreach ($classes as $classPath) { $class = sprintf('\\App\\Controller\\Cron\\%s', $this->utils->filename($classPath)); if (class_exists($class)) { if ($reflector = new ReflectionClass($class)) { foreach ($reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { if (!preg_match('/^\\_/', $method->name)) { $controller = ['type' => ucwords(basename(dirname($classPath, 4))), 'value' => sprintf("%s@%s", $method->class, $method->name), 'name' => sprintf("%s@%s", $this->utils->filename($method->class), $method->name)]; array_push($controllers, $controller); } } } } } } return (new View())->with(new Helper('NyaSelect'))->set('controllers', $controllers); }
public function update(UserUpdateDataEvent $event) { if ($user = $event->getUser()) { $fields = array_diff($this->database->getColumns($user->getTable()), ['user_id', 'ident', 'created_at', 'updated_at']); $userDataModel = $this->resolver->getModel('UserData', true); foreach ($event->getNewData() as $key => $value) { if (in_array($key, $fields)) { if ($event->isOverwrite() || empty($user->{$key}) || $key === 'verified' && $value === 'true') { $dataChanged = $dataChanged ?? $user->{$key} !== $value; $user->{$key} = $key === 'password' ? password_hash($value, PASSWORD_DEFAULT) : $value; } } elseif (!empty($userDataModel)) { /** @var MUserDatum $extra */ $extra = $userDataModel::firstOrCreate(['user_id' => $user->user_id, 'key' => $key]); if ($event->isOverwrite() || empty($extra->data)) { if (!empty($value)) { $extra->data = $value; $extra->save(); } else { $extra->delete(); } } } else { $event->setError('INVALID_FIELD'); throw new UserUpdateDataError("Field {$key} not found in users table"); } } if (!empty($dataChanged)) { if ($user->save()) { $event->setHandled(true); } } else { $event->setHandled(true); } } else { $event->setError('INVALID_USER'); } }
/** * @return \Minute\Model\ModelEx */ protected function getConfigModel() { return $this->database->isConnected() ? $this->resolver->getModel('Config', true) : null; }