From ad2258607a505c8bb9bb48de7abc3b23bcdb3707 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 4 Oct 2018 09:44:25 +0200 Subject: [PATCH 01/23] migration: 20181003134001_user_type.php --- app/migrations/20181003134001_user_type.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/migrations/20181003134001_user_type.php diff --git a/app/migrations/20181003134001_user_type.php b/app/migrations/20181003134001_user_type.php new file mode 100644 index 0000000..20f02b1 --- /dev/null +++ b/app/migrations/20181003134001_user_type.php @@ -0,0 +1,19 @@ +table('user') + ->addColumn('type', 'enum', [ + 'null' => false, + 'default' => 'user', + 'values' => [ 'user', 'admin' ], + 'after' => 'regdate' + ]) + ->save(); + } +} From 388b5933cb36d92074986dc61d3bcebf3db499ce Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 4 Oct 2018 09:45:04 +0200 Subject: [PATCH 02/23] app/models/Data/User.php: add type field. --- app/models/Data/User.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/models/Data/User.php b/app/models/Data/User.php index 335a874..2865371 100644 --- a/app/models/Data/User.php +++ b/app/models/Data/User.php @@ -9,6 +9,9 @@ use Phalcon\Validation, class User extends Base { + const TYPE_USER = 'user'; + const TYPE_ADMIN = 'admin'; + const STATUS_ACTIVE = 'Active'; const STATUS_DELETED = 'Deleted'; const STATUS_SUSPENDED = 'Suspended'; @@ -23,6 +26,8 @@ class User extends Base protected $email; + protected $type; + protected $status; protected $password; @@ -203,6 +208,24 @@ class User extends Base return $this; } + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $type + * @return User + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + /** * @return string */ From f276ad92a822caff2c236afb370328df06767297 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 4 Oct 2018 09:46:00 +0200 Subject: [PATCH 03/23] app/listeners/AccessListener.php: fetch role from identity. --- app/listeners/AccessListener.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/listeners/AccessListener.php b/app/listeners/AccessListener.php index 92468e0..dc2366e 100644 --- a/app/listeners/AccessListener.php +++ b/app/listeners/AccessListener.php @@ -24,10 +24,13 @@ class AccessListener extends Plugin */ public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher) : bool { - // We only have two roles for now, authenticated users and guests. + // If we have an identity, fetch type from authed user. if ($this->auth->hasIdentity()) { - $role = Acl::ROLE_USER; - } else { + $user = $this->auth->getUser(); + $role = $user->getType(); + } + // Othersize, we default to role. + else { $role = Acl::ROLE_GUEST; } From 884f721002daa2cbd59a2cd08fc608b092c91170 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 4 Oct 2018 09:46:23 +0200 Subject: [PATCH 04/23] app/config/acl.yml: add admin role. --- app/config/acl.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/config/acl.yml b/app/config/acl.yml index 0f27795..8e36835 100644 --- a/app/config/acl.yml +++ b/app/config/acl.yml @@ -32,8 +32,9 @@ acl: inherits: guest allowed-zones: user description: Logged in users - #admin: - # inherits: user + admin: + inherits: user + description: Administrators # allowed-zones: backend zones: From e5b0e1fcfd16902ca822d10256c39cef4eeb8b4f Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 9 Oct 2018 22:26:01 +0200 Subject: [PATCH 05/23] Make the application modular to have a "main" and "backend" part. --- app/config/app.yml | 3 +- app/config/routes.yml | 5 ++ app/controllers/backend/UserController.php | 10 ++++ app/library/Bootstrap.php | 19 +++++++- app/library/Services.php | 3 +- app/modules/Backend.php | 12 +++++ app/modules/Base.php | 47 +++++++++++++++++++ app/modules/Main.php | 12 +++++ .../_components}/content-section.volt | 0 .../_components}/flash.volt | 0 .../_components}/footer.volt | 0 .../_components}/navigation.volt | 0 .../{ => _common}/_partials/pagination.volt | 0 app/views/{ => _common}/layout-front.volt | 0 app/views/{ => _common}/layout.volt | 6 +-- app/views/backend/user/index.volt | 2 + app/views/{ => main}/auth/index.volt | 0 app/views/{ => main}/auth/register.volt | 0 app/views/{ => main}/callback/created.volt | 0 app/views/{ => main}/callback/list.volt | 0 app/views/{ => main}/callback/new.volt | 0 app/views/{ => main}/callback/show.volt | 0 app/views/{ => main}/error/error.volt | 0 app/views/{ => main}/error/show404.volt | 0 app/views/{ => main}/index/about.volt | 0 app/views/{ => main}/index/index.volt | 0 app/views/{ => main}/user/activity.volt | 0 app/views/{ => main}/user/settings.volt | 0 28 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 app/controllers/backend/UserController.php create mode 100644 app/modules/Backend.php create mode 100644 app/modules/Base.php create mode 100644 app/modules/Main.php rename app/views/{_templates => _common/_components}/content-section.volt (100%) rename app/views/{_templates => _common/_components}/flash.volt (100%) rename app/views/{_templates => _common/_components}/footer.volt (100%) rename app/views/{_templates => _common/_components}/navigation.volt (100%) rename app/views/{ => _common}/_partials/pagination.volt (100%) rename app/views/{ => _common}/layout-front.volt (100%) rename app/views/{ => _common}/layout.volt (78%) create mode 100644 app/views/backend/user/index.volt rename app/views/{ => main}/auth/index.volt (100%) rename app/views/{ => main}/auth/register.volt (100%) rename app/views/{ => main}/callback/created.volt (100%) rename app/views/{ => main}/callback/list.volt (100%) rename app/views/{ => main}/callback/new.volt (100%) rename app/views/{ => main}/callback/show.volt (100%) rename app/views/{ => main}/error/error.volt (100%) rename app/views/{ => main}/error/show404.volt (100%) rename app/views/{ => main}/index/about.volt (100%) rename app/views/{ => main}/index/index.volt (100%) rename app/views/{ => main}/user/activity.volt (100%) rename app/views/{ => main}/user/settings.volt (100%) diff --git a/app/config/app.yml b/app/config/app.yml index 398b1cf..a486196 100644 --- a/app/config/app.yml +++ b/app/config/app.yml @@ -1,9 +1,10 @@ application: + modulesDir : ../app/modules/ controllersDir : ../app/controllers/ modelsDir : ../app/models/ migrationsDir : ../app/migrations/ - viewsDir : ../app/views/ + viewsDir : ../app/views/_common/ templateDir : ../app/templates/ listenersDir : ../app/listeners/ libraryDir : ../app/library/ diff --git a/app/config/routes.yml b/app/config/routes.yml index 7b0f625..aba0eda 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -56,3 +56,8 @@ router: path: controller: api action: activationlink + + # Backend + backend-home: + pattern: '/admin' + path: backend::user::index diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php new file mode 100644 index 0000000..88a4e4f --- /dev/null +++ b/app/controllers/backend/UserController.php @@ -0,0 +1,10 @@ +setDI($di); + + $this->_app = new Application(); } /** @@ -34,6 +41,14 @@ class Bootstrap extends Injectable $di->get('debugger')->listen(true, true); } + // Modules + $this->_app->registerModules([ + 'main' => [ 'className' => 'App\Module\Main' ], + 'backend' => [ 'className' => 'App\Module\Backend' ], + ]); + + $this->_app->setDefaultModule('main'); + return $this; } @@ -44,7 +59,7 @@ class Bootstrap extends Injectable */ public function run() { - $app = new Application($this->getDI()); - return $app->handle()->getContent(); + $this->_app->setDI($this->getDI()); + return $this->_app->handle()->getContent(); } } diff --git a/app/library/Services.php b/app/library/Services.php index af06def..c6b8ef3 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -99,6 +99,7 @@ class Services extends DiDefault $loader->registerNamespaces(array( 'App\Controller' => $config->application->controllersDir, 'App\Listener' => $config->application->listenersDir, + 'App\Module' => $config->application->modulesDir, 'App\Model' => $config->application->modelsDir, 'App\Form' => $config->application->formsDir, 'Httpcb' => $config->application->libraryDir, @@ -222,7 +223,7 @@ class Services extends DiDefault $view = new View(); - $view->setViewsDir($config->application->viewsDir); + $view->setViewsDir([ $config->application->viewsDir ]); $view->setLayoutsDir('_layouts/'); $view->setPartialsDir('_partials/'); diff --git a/app/modules/Backend.php b/app/modules/Backend.php new file mode 100644 index 0000000..aa1ca6e --- /dev/null +++ b/app/modules/Backend.php @@ -0,0 +1,12 @@ +registerNamespaces([ + $this->_controllerNamespace => $this->_controllerPath, + ]); + + $loader->register(); + } + + /** + * Register specific services for the module + */ + public function registerServices(DiInterface $di) + { + $dispatcher = $di->get('dispatcher'); + + $dispatcher->setDefaultNamespace($this->_controllerNamespace); + + $di->get('view')->setViewsDir(array_merge( + [ $this->_viewDir ], + (array) $di->get('view')->getViewsDir() + )); + } +} + diff --git a/app/modules/Main.php b/app/modules/Main.php new file mode 100644 index 0000000..5e397b0 --- /dev/null +++ b/app/modules/Main.php @@ -0,0 +1,12 @@ +
- {% include "_templates/navigation.volt" %} + {% include "_components/navigation.volt" %}
{% block masthead %}{% endblock %} @@ -20,14 +20,14 @@
- {% include "_templates/flash.volt" %} + {% include "_components/flash.volt" %} {{ content() }}
{{ assets.outputJs() }} diff --git a/app/views/backend/user/index.volt b/app/views/backend/user/index.volt new file mode 100644 index 0000000..f12e351 --- /dev/null +++ b/app/views/backend/user/index.volt @@ -0,0 +1,2 @@ + +

Backend

diff --git a/app/views/auth/index.volt b/app/views/main/auth/index.volt similarity index 100% rename from app/views/auth/index.volt rename to app/views/main/auth/index.volt diff --git a/app/views/auth/register.volt b/app/views/main/auth/register.volt similarity index 100% rename from app/views/auth/register.volt rename to app/views/main/auth/register.volt diff --git a/app/views/callback/created.volt b/app/views/main/callback/created.volt similarity index 100% rename from app/views/callback/created.volt rename to app/views/main/callback/created.volt diff --git a/app/views/callback/list.volt b/app/views/main/callback/list.volt similarity index 100% rename from app/views/callback/list.volt rename to app/views/main/callback/list.volt diff --git a/app/views/callback/new.volt b/app/views/main/callback/new.volt similarity index 100% rename from app/views/callback/new.volt rename to app/views/main/callback/new.volt diff --git a/app/views/callback/show.volt b/app/views/main/callback/show.volt similarity index 100% rename from app/views/callback/show.volt rename to app/views/main/callback/show.volt diff --git a/app/views/error/error.volt b/app/views/main/error/error.volt similarity index 100% rename from app/views/error/error.volt rename to app/views/main/error/error.volt diff --git a/app/views/error/show404.volt b/app/views/main/error/show404.volt similarity index 100% rename from app/views/error/show404.volt rename to app/views/main/error/show404.volt diff --git a/app/views/index/about.volt b/app/views/main/index/about.volt similarity index 100% rename from app/views/index/about.volt rename to app/views/main/index/about.volt diff --git a/app/views/index/index.volt b/app/views/main/index/index.volt similarity index 100% rename from app/views/index/index.volt rename to app/views/main/index/index.volt diff --git a/app/views/user/activity.volt b/app/views/main/user/activity.volt similarity index 100% rename from app/views/user/activity.volt rename to app/views/main/user/activity.volt diff --git a/app/views/user/settings.volt b/app/views/main/user/settings.volt similarity index 100% rename from app/views/user/settings.volt rename to app/views/main/user/settings.volt From c94c0fed7bb72a41a208abadf583ddb16ed020f0 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 10 Oct 2018 00:19:58 +0200 Subject: [PATCH 06/23] app/listeners/AccessListener.php: implement modules. --- app/listeners/AccessListener.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/listeners/AccessListener.php b/app/listeners/AccessListener.php index dc2366e..e51301c 100644 --- a/app/listeners/AccessListener.php +++ b/app/listeners/AccessListener.php @@ -34,8 +34,7 @@ class AccessListener extends Plugin $role = Acl::ROLE_GUEST; } - // Get the resource from controller name. - $resource = $dispatcher->getControllerName(); + $resource = $this->_getCurrentResource($dispatcher); // Ignore checks for error resource. if (in_array($resource, $this->_ignored_resources)) { @@ -70,4 +69,15 @@ class AccessListener extends Plugin } return true; } + + protected function _getCurrentResource($dispatcher) + { + // If default module, only fetch controller name. + if (strlen($dispatcher->getModuleName()) < 1) { + return $dispatcher->getControllerName(); + } + + // Otherwise, we follow the syntax "/" + return "{$dispatcher->getModuleName()}/{$dispatcher->getControllerName()}"; + } } From 2cb7ad2da892eb36c1cf021a6a8aacde588999af Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 10 Oct 2018 00:27:11 +0200 Subject: [PATCH 07/23] app/library/Acl.php: in isAllowed() implement wildcard for controllers in modules. --- app/library/Acl.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/library/Acl.php b/app/library/Acl.php index 80a3157..b7814b7 100644 --- a/app/library/Acl.php +++ b/app/library/Acl.php @@ -33,6 +33,19 @@ class Acl */ public function isAllowed($role, $resource) { + // Special stuff here :) for resources within modules. + + // Modules and controllers are separated by "/" + $pos = strpos($resource, '/'); + if ($pos !== false) { + // Construct the wildcard resource. + $wildcard = substr($resource, 0, $pos+1) . '*'; + + // If we have this wildcard resource, check against that instead. + if ($this->hasResource($wildcard)) { + $resource = $wildcard; + } + } return $this->_adapter->isAllowed($role, $resource, 'All') == \Phalcon\Acl::ALLOW; } From 4e059b3c545b7dbabb4f0b0e93420b1f69c6bed6 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 10 Oct 2018 00:28:26 +0200 Subject: [PATCH 08/23] app/library/Acl.php: in fromConfig() fix so that zones can be both strings and arrays. --- app/library/Acl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/library/Acl.php b/app/library/Acl.php index b7814b7..f00ac8c 100644 --- a/app/library/Acl.php +++ b/app/library/Acl.php @@ -98,7 +98,8 @@ class Acl } foreach($zones as $zone) { - foreach($config->zones->get($zone) as $resource) { + $resources = (array) $config->zones->get($zone); + foreach($resources as $resource) { $this->_adapter->allow($name, $resource, 'All'); } } From 8aa1ceb2cb6ec5753bcbc686cd6d4f46362c0691 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 10 Oct 2018 00:28:51 +0200 Subject: [PATCH 09/23] app/config/acl.yml: add admin role and backend zone. --- app/config/acl.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/config/acl.yml b/app/config/acl.yml index 8e36835..0c543df 100644 --- a/app/config/acl.yml +++ b/app/config/acl.yml @@ -8,7 +8,12 @@ # "allowed-zones" key. Per default a role is denied access to all zones. # # - Resources: -# Resources maps directly to controller names. +# Resources maps directly to controller names. If a controller is not +# under the default module. / format is used instead. +# +# A special wildcard "*" character can be used to allow access to all +# controllers (most likely only useful for non-default modules). +# # There a 2 controllers/resources that are a bit special, # index and error resources are always accessible by everyone (e.g. they # are not part of the ACL). @@ -18,10 +23,8 @@ # # Zones # -# Zones defines a group of resources. for example an "backend" zone can +# Zones defines as 1 or more resources. for example an "backend" zone can # have 2 controllers/resources (site-config, user-manager) -# -# Zones might be implemented using modules later. acl: roles: @@ -35,9 +38,9 @@ acl: admin: inherits: user description: Administrators - # allowed-zones: backend + allowed-zones: backend zones: public: [ auth, api ] user: [ user, callback ] - #backend: [ site, user-man ] + backend: backend/* From cc08ca165880ecfecd16ddcff7176e6673495fea Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 2 Dec 2018 20:21:58 +0100 Subject: [PATCH 10/23] app/config/acl.yml: move the docs to docs/ACL.md --- app/config/acl.yml | 27 ------------------ docs/ACL.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 27 deletions(-) create mode 100644 docs/ACL.md diff --git a/app/config/acl.yml b/app/config/acl.yml index 0c543df..738bcfc 100644 --- a/app/config/acl.yml +++ b/app/config/acl.yml @@ -1,31 +1,4 @@ -# ACL in this system is defined as follows: -# -# - Roles: -# Roles define a group of user. like Author, Admin, Guest etc. -# Each role can inherit other roles with the "inherit" key. -# Each role can gain access to a zone (explained later) by the -# "allowed-zones" key. Per default a role is denied access to all zones. -# -# - Resources: -# Resources maps directly to controller names. If a controller is not -# under the default module. / format is used instead. -# -# A special wildcard "*" character can be used to allow access to all -# controllers (most likely only useful for non-default modules). -# -# There a 2 controllers/resources that are a bit special, -# index and error resources are always accessible by everyone (e.g. they -# are not part of the ACL). -# -# - Access levels. -# These are not used in this system. a hardcoded "All" level is used. -# -# Zones -# -# Zones defines as 1 or more resources. for example an "backend" zone can -# have 2 controllers/resources (site-config, user-manager) - acl: roles: guest: diff --git a/docs/ACL.md b/docs/ACL.md new file mode 100644 index 0000000..1e3ccba --- /dev/null +++ b/docs/ACL.md @@ -0,0 +1,68 @@ + +# ACL + +The ACL is defined as follows: + +## Roles + +Roles define a group of user. like Author, Admin, Guest etc. +Each role can inherit other roles with the "inherit" key. +Each role can gain access to a zone (explained later) by the +"allowed-zones" key. Per default a role is denied access to all zones. + +## Resources + +Resources maps directly to `controller` names. If a controller is not +under the default module. `/` format is used instead. + +A special wildcard `*` character can be used to allow access to all +controllers (most likely only useful for non-default modules). + +For example the resource `backend/*` Matches all controllers under +the backend module. + +### Special controllers. + +There a 2 controllers that are a bit special, +`index` and `error` resources are always accessible by everyone (e.g. they +are not part of the ACL). + +## Access levels. + +These are not used in this system. a hardcoded "All" level is used. + +## Zones + +Zones defines as 1 or more resources. for example an "backend" zone can +have 2 controllers/resources (*site-config*, *user-manager*) + +Zones can also defines entire modules + + +# Example config. + +acl.yml +```yaml +acl: + roles: + guest: # Guests are only allowed to access the public zone. + allowed-zones: public + description: Non logged in users + user: # Users inherits the guest role + has access to user zone. + inherits: guest + allowed-zones: user + description: Logged in users + admin: # Admins inherits the user role + has access to backend zone. + inherits: user + description: Administrators + allowed-zones: backend + + zones: + # Public zone is the start page in + # index controller + login/logout in auth. + public: [ auth ] + # User zone can access profile and settings controllers + user: [ profile, settings ] + # Backend zone is the entire backend module. + backend: backend/* +``` From ca27834a564549368eb29d13884f1f99e0077b2a Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 29 Dec 2018 00:41:08 +0100 Subject: [PATCH 11/23] app/library/Navigation/Node.php: minor change. --- app/library/Navigation/Node.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/library/Navigation/Node.php b/app/library/Navigation/Node.php index 5f9d420..fb1f6b6 100644 --- a/app/library/Navigation/Node.php +++ b/app/library/Navigation/Node.php @@ -183,11 +183,11 @@ class Node extends Container // Assemble route if set. if (strlen($this->getRoute()) > 0) { - $href = array( + $href = [ 'for' => $this->getRoute(), 'controller' => $this->getController(), 'action' => $this->getAction() - ); + ]; } // Otherwise, use default route. else { From 89e096c4fd4a861129d1633174ac5e6ff7ac5ec2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 29 Dec 2018 01:04:59 +0100 Subject: [PATCH 12/23] app/library/Services.php: get role from authed user getType() method. --- app/library/Services.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/library/Services.php b/app/library/Services.php index c6b8ef3..a6157f5 100644 --- a/app/library/Services.php +++ b/app/library/Services.php @@ -289,7 +289,8 @@ class Services extends DiDefault $menu = new Menu($navigation); $menu->setMenuClass(null); if ($this->get('auth')->hasIdentity()) { - $menu->setAclRole(Acl::ROLE_USER); + $type = $this->get('auth')->getIdentity()->getType(); + $menu->setAclRole($type); } else { $menu->setAclRole(Acl::ROLE_GUEST); } From 3c17346e46098467aaab236fb70ad49adb87d477 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 29 Dec 2018 15:45:40 +0100 Subject: [PATCH 13/23] app/config/menu.yml: add admin link --- app/config/menu.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/config/menu.yml b/app/config/menu.yml index 5aa188e..65d24ec 100644 --- a/app/config/menu.yml +++ b/app/config/menu.yml @@ -25,3 +25,10 @@ menu: route: about-route controller: index action: about + admin: + caption: Admin + resource: backend/user + controller: user + action: index + route: backend-home + From dfe440cda344fe373d89711a7963cdf4cde28cf5 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 29 Dec 2018 16:46:46 +0100 Subject: [PATCH 14/23] app/models/Data/User.php: adding getPagination() --- app/models/Data/User.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/models/Data/User.php b/app/models/Data/User.php index 2865371..122ba68 100644 --- a/app/models/Data/User.php +++ b/app/models/Data/User.php @@ -455,4 +455,24 @@ class User extends Base } } } + + /** + * @param int $page + * @param int $limit + * @return \Phalcon\Paginator\AdapterInterface + */ + public static function getPaginationList($page = 1, $limit = 30) + { + $builder = (new self())->getModelsManager()->createBuilder(); + + $builder->from(self::class); + + $paginator = new \Phalcon\Paginator\Adapter\QueryBuilder(array( + 'builder' => $builder, + 'page' => $page, + 'limit' => $limit + )); + + return $paginator; + } } From 7c458a8052967645526db960e906e5c8d5ce08f1 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 29 Dec 2018 16:49:42 +0100 Subject: [PATCH 15/23] app/config/routes.yml: adding backend-user-list route --- app/config/routes.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/config/routes.yml b/app/config/routes.yml index aba0eda..1d71e24 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -61,3 +61,6 @@ router: backend-home: pattern: '/admin' path: backend::user::index + backend-user-list: + pattern: '/admin/user/list/{page:([0-9]+)}' + path: backend::user::index From bdde1d9ac7e30add06970b7c227999119ae39061 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 29 Dec 2018 16:50:20 +0100 Subject: [PATCH 16/23] app/controllers/backend/UserController.php: adding listing of users. --- app/controllers/backend/UserController.php | 11 ++++++- app/views/backend/user/index.volt | 36 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index 88a4e4f..c0c6bf4 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -2,9 +2,18 @@ namespace App\Controller\Backend; +use App\Model\Data\User; + class UserController extends \Phalcon\Mvc\Controller { - public function indexAction() + /** + * @param $page + */ + public function indexAction($page = 1) { + $paginator = User::getPaginationList($page,15); + + $this->view->pagination_url = '/admin/user/list/'; + $this->view->page = $paginator->getPaginate(); } } diff --git a/app/views/backend/user/index.volt b/app/views/backend/user/index.volt index f12e351..13c539e 100644 --- a/app/views/backend/user/index.volt +++ b/app/views/backend/user/index.volt @@ -1,2 +1,36 @@ -

Backend

+
+ +

Users

+ + + + + + + + + + + + + + + + {% for item in page.items %} + + + + + + + + + {% endfor %} + +
#UsernameNameEmailTypeStatus
{{ item.id }}{{ item.username }}{{ item.name }}{{ item.email }}{{ item.type }}{{ item.status }}
+ + +
From 223d78d7d43ba7ce1265a63f9f37c543c7326256 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 31 Dec 2018 00:12:21 +0100 Subject: [PATCH 17/23] scss: adding views/_backend.scss --- app/assets/sass/application.scss | 1 + app/assets/sass/views/_backend.scss | 34 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 app/assets/sass/views/_backend.scss diff --git a/app/assets/sass/application.scss b/app/assets/sass/application.scss index a1f7d81..f44df01 100644 --- a/app/assets/sass/application.scss +++ b/app/assets/sass/application.scss @@ -44,3 +44,4 @@ @import "views/about"; @import "views/login"; @import "views/register"; +@import "views/backend"; diff --git a/app/assets/sass/views/_backend.scss b/app/assets/sass/views/_backend.scss new file mode 100644 index 0000000..ee74ef0 --- /dev/null +++ b/app/assets/sass/views/_backend.scss @@ -0,0 +1,34 @@ + +.backend { + display: flex; + background-color: $section-bg; + border-radius: 2px; + @include box-shadow($block-shadow-3); + + &-sidemenu { + @extend .list-group; + width: 15%; + background-color: darken($section-bg, 4%); + border: 1px solid darken($section-bg, 8%); + > li { + list-style: none; + + a { + display: block; + color: $text-secondary-color; + padding: .8em 1.6em; + + &:hover { + background: darken($section-bg, 8%); + color: $text-color; + text-decoration: none; + } + } + } + } + + &-content { + width: 85%; + padding: $section-padding; + } +} From bed7b3674800170fcf179165ce1b709fa49b8dd6 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 31 Dec 2018 00:14:47 +0100 Subject: [PATCH 18/23] adding app/views/backend/_layouts/side-menu.volt --- app/views/backend/_layouts/side-menu.volt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/views/backend/_layouts/side-menu.volt diff --git a/app/views/backend/_layouts/side-menu.volt b/app/views/backend/_layouts/side-menu.volt new file mode 100644 index 0000000..3208087 --- /dev/null +++ b/app/views/backend/_layouts/side-menu.volt @@ -0,0 +1,19 @@ + + + + + From 34d2c048f5798fe696aa97cf6de59f4812440436 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Mon, 31 Dec 2018 00:15:08 +0100 Subject: [PATCH 19/23] app/controllers/backend/UserController.php: use the side-menu layout --- app/controllers/backend/UserController.php | 5 ++ app/views/backend/user/index.volt | 59 ++++++++++------------ 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/app/controllers/backend/UserController.php b/app/controllers/backend/UserController.php index c0c6bf4..bde79ac 100644 --- a/app/controllers/backend/UserController.php +++ b/app/controllers/backend/UserController.php @@ -6,6 +6,11 @@ use App\Model\Data\User; class UserController extends \Phalcon\Mvc\Controller { + public function onConstruct() + { + $this->view->setLayout('side-menu'); + } + /** * @param $page */ diff --git a/app/views/backend/user/index.volt b/app/views/backend/user/index.volt index 13c539e..5ccaad4 100644 --- a/app/views/backend/user/index.volt +++ b/app/views/backend/user/index.volt @@ -1,36 +1,33 @@ -
+

Users

-

Users

+ -
+ + + + + + + + + + - - - - - - - - - - + + {% for item in page.items %} + + + + + + + + + {% endfor %} + +
#UsernameNameEmailTypeStatus
#UsernameNameEmailTypeStatus
{{ item.id }}{{ item.username }}{{ item.name }}{{ item.email }}{{ item.type }}{{ item.status }}
- - {% for item in page.items %} - - {{ item.id }} - {{ item.username }} - {{ item.name }} - {{ item.email }} - {{ item.type }} - {{ item.status }} - - {% endfor %} - - - - -
+ From a01cc602662191f7e17492ce18d7454944607832 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 1 Dec 2019 19:23:58 +0100 Subject: [PATCH 20/23] app/models/Data/ActivityLog.php: Add relationship to User model. --- app/models/Data/ActivityLog.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/models/Data/ActivityLog.php b/app/models/Data/ActivityLog.php index 91f3158..1f3da51 100644 --- a/app/models/Data/ActivityLog.php +++ b/app/models/Data/ActivityLog.php @@ -16,6 +16,15 @@ class ActivityLog extends Base protected $message; + /** + * Initialize method for model. + */ + public function initialize() + { + // Relationships + $this->hasOne('user_id', User::class, 'id', ['alias' => 'User']); + } + /** * @return mixed */ From 778c7127b348e29db81666d1c1a396ad15c0a8a2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 1 Dec 2019 19:24:27 +0100 Subject: [PATCH 21/23] app/models/Data/ActivityLog.php: implement getAllPaginationList() --- app/models/Data/ActivityLog.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/models/Data/ActivityLog.php b/app/models/Data/ActivityLog.php index 1f3da51..1bf3c9b 100644 --- a/app/models/Data/ActivityLog.php +++ b/app/models/Data/ActivityLog.php @@ -2,7 +2,8 @@ namespace App\Model\Data; -use \Phalcon\Paginator\Adapter\QueryBuilder; +use Phalcon\Mvc\Model\Query\BuilderInterface, + Phalcon\Paginator\Adapter\QueryBuilder; class ActivityLog extends Base { @@ -129,6 +130,26 @@ class ActivityLog extends Base ->where('user_id = :uid:', array('uid' => $userid)) ->orderBy('timestamp DESC'); + return self::_paginate($builder, $page, $limit); + } + + /** + * @param int $page + * @param int $limit + * @return \Phalcon\Paginator\AdapterInterface + */ + public static function getAllPaginationList($page = 1, $limit = 30) + { + $builder = (new self())->getModelsManager()->createBuilder(); + + $builder->from(self::class) + ->orderBy('timestamp DESC'); + + return self::_paginate($builder, $page, $limit); + } + + protected static function _paginate(BuilderInterface $builder, $page = 1, $limit = 30) + { $paginator = new QueryBuilder(array( 'builder' => $builder, 'page' => $page, From 5fb9880a1b9b11a7340e1a8a9de9c542ee974564 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 1 Dec 2019 19:24:52 +0100 Subject: [PATCH 22/23] Adding backend/LogController::index() --- app/config/routes.yml | 3 ++ app/controllers/backend/LogController.php | 21 ++++++++++++++ app/views/backend/log/index.volt | 34 +++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 app/controllers/backend/LogController.php create mode 100644 app/views/backend/log/index.volt diff --git a/app/config/routes.yml b/app/config/routes.yml index 1d71e24..5510b37 100644 --- a/app/config/routes.yml +++ b/app/config/routes.yml @@ -64,3 +64,6 @@ router: backend-user-list: pattern: '/admin/user/list/{page:([0-9]+)}' path: backend::user::index + backend-log: + pattern: '/admin/log{page:/?([0-9]+)?}' + path: backend::log::index diff --git a/app/controllers/backend/LogController.php b/app/controllers/backend/LogController.php new file mode 100644 index 0000000..dcbe8fb --- /dev/null +++ b/app/controllers/backend/LogController.php @@ -0,0 +1,21 @@ +view->setLayout('side-menu'); + } + + public function indexAction($page = 1) + { + $paginator = ActivityLog::getAllPaginationList($page); + + $this->view->page = $paginator->getPaginate(); + $this->view->pagination_url = '/admin/log/'; + } +} diff --git a/app/views/backend/log/index.volt b/app/views/backend/log/index.volt new file mode 100644 index 0000000..c0a8535 --- /dev/null +++ b/app/views/backend/log/index.volt @@ -0,0 +1,34 @@ + +

Activity Log

+ + + + + + + + + + + + + {% for item in page.items %} + + + + + + + {% endfor %} + +
DateIpUserMessage
{{ item.getTimestamp() }}{{ item.getIp() }} + {% if item.getUser() %} + {{ item.getUser().getId() }}:{{ item.getUser().getUsername() }} + {% else %} + - + {% endif %} + {{ item.getMessage() }}
+ + From fcefe72c55aab817e3014cecf2b1fcbecbca2917 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 1 Dec 2019 23:58:41 +0100 Subject: [PATCH 23/23] app/assets/sass/views/_backend.scss: make sure we have some margin-bottom so content below are pushed down abit. --- app/assets/sass/views/_backend.scss | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/assets/sass/views/_backend.scss b/app/assets/sass/views/_backend.scss index ee74ef0..519fd47 100644 --- a/app/assets/sass/views/_backend.scss +++ b/app/assets/sass/views/_backend.scss @@ -1,9 +1,8 @@ .backend { display: flex; - background-color: $section-bg; - border-radius: 2px; - @include box-shadow($block-shadow-3); + @extend .section; + padding: 0; &-sidemenu { @extend .list-group;