Commit 963a3b62239b89ef79c5240a7a4e9ae554ccfb02

Authored by Alex Savenko
1 parent eaa74332

extended classes

app/library/App/Mvc/ExtendedApiCollection.php
1 1 <?php
2   -/**
3   - * Created by PhpStorm.
4   - * User: Alex Savenko
5   - * Date: 14.02.2017
6   - * Time: 16:32
7   - */
8 2  
9 3 namespace App\Mvc;
10 4  
11   -
  5 +use Phalcon\Acl;
  6 +use Phalcon\Mvc\Micro\CollectionInterface;
  7 +use PhalconApi\Acl\MountableInterface;
  8 +use PhalconApi\Constants\ErrorCodes;
12 9 use PhalconApi\Constants\HttpMethods;
13   -use PhalconRest\Api\ApiCollection;
  10 +use PhalconApi\Constants\PostedDataMethods;
  11 +use PhalconApi\Core;
  12 +use PhalconApi\Exception;
  13 +
  14 +class ExtendedApiCollection extends \Phalcon\Mvc\Micro\Collection implements MountableInterface, CollectionInterface
  15 +{
  16 + protected $name;
  17 + protected $description;
  18 +
  19 + protected $allowedRoles = [];
  20 + protected $deniedRoles = [];
  21 +
  22 + protected $postedDataMethod = PostedDataMethods::AUTO;
  23 +
  24 + protected $endpointsByName = [];
  25 +
  26 +
  27 + public function __construct($prefix)
  28 + {
  29 + parent::setPrefix($prefix);
  30 +
  31 + $this->initialize();
  32 + }
  33 +
  34 + /**
  35 + * Use this method when you extend this class in order to define the collection
  36 + */
  37 + protected function initialize()
  38 + {
  39 + }
  40 +
  41 + /**
  42 + * Returns collection with default values
  43 + *
  44 + * @param string $prefix Prefix for the collection (e.g. /auth)
  45 + * @param string $name Name for the collection (e.g. authentication) (optional)
  46 + *
  47 + * @return static
  48 + */
  49 + public static function factory($prefix, $name = null)
  50 + {
  51 + $calledClass = get_called_class();
14 52  
15   -class ExtendedApiCollection extends ApiCollection {
  53 + /** @var \App\Mvc\ExtendedApiCollection $collection */
  54 + $collection = new $calledClass($prefix);
16 55  
  56 + if ($name) {
  57 + $collection->name($name);
  58 + }
  59 +
  60 + return $collection;
  61 + }
  62 +
  63 + /**
  64 + * @param string $name Name for the collection
  65 + *
  66 + * @return static
  67 + */
  68 + public function name($name)
  69 + {
  70 + $this->name = $name;
  71 + return $this;
  72 + }
  73 +
  74 + /**
  75 + * @param string $description Description of the collection
  76 + *
  77 + * @return static
  78 + */
  79 + public function description($description)
  80 + {
  81 + $this->description = $description;
  82 + return $this;
  83 + }
  84 +
  85 + /**
  86 + * @return string Description of the collection
  87 + */
  88 + public function getDescription()
  89 + {
  90 + return $this->description;
  91 + }
  92 +
  93 + public function setPrefix($prefix)
  94 + {
  95 + throw new Exception(ErrorCodes::GENERAL_SYSTEM, null, 'Setting prefix after initialization is prohibited.');
  96 + }
  97 +
  98 + public function handler($handler, $lazy = true)
  99 + {
  100 + $this->setHandler($handler, $lazy);
  101 + return $this;
  102 + }
  103 +
  104 + /**
  105 + * Mounts endpoint to the collection
  106 + *
  107 + * @param \App\Mvc\ExtendedApiEndpoint $endpoint Endpoint to mount (shortcut for endpoint function)
  108 + *
  109 + * @return static
  110 + */
  111 + public function mount(ExtendedApiEndpoint $endpoint)
  112 + {
  113 + $this->endpoint($endpoint);
  114 + return $this;
  115 + }
  116 +
  117 + /**
  118 + * Mounts endpoint to the collection
  119 + *
  120 + * @param \App\Mvc\ExtendedApiEndpoint $endpoint Endpoint to mount
  121 + *
  122 + * @return static
  123 + */
17 124 public function endpoint(ExtendedApiEndpoint $endpoint)
18 125 {
19 126 $this->endpointsByName[$endpoint->getName()] = $endpoint;
... ... @@ -44,4 +151,208 @@ class ExtendedApiCollection extends ApiCollection {
44 151 return $this;
45 152 }
46 153  
47   -}
48 154 \ No newline at end of file
  155 + protected function createRouteName(ExtendedApiEndpoint $endpoint)
  156 + {
  157 + return serialize([
  158 + 'collection' => $this->getIdentifier(),
  159 + 'endpoint' => $endpoint->getIdentifier()
  160 + ]);
  161 + }
  162 +
  163 + /**
  164 + * @return string Unique identifier for this collection (returns the prefix)
  165 + */
  166 + public function getIdentifier()
  167 + {
  168 + return $this->getPrefix();
  169 + }
  170 +
  171 + /**
  172 + * @return \App\Mvc\ExtendedApiEndpoint[] Array of all mounted endpoints
  173 + */
  174 + public function getEndpoints()
  175 + {
  176 + return array_values($this->endpointsByName);
  177 + }
  178 +
  179 + /**
  180 + * @param string $name Name for the endpoint to return
  181 + *
  182 + * @return \App\Mvc\ExtendedApiEndpoint|null Endpoint with the given name
  183 + */
  184 + public function getEndpoint($name)
  185 + {
  186 + return array_key_exists($name, $this->endpointsByName) ? $this->endpointsByName[$name] : null;
  187 + }
  188 +
  189 + /**
  190 + * @return string $method One of the method constants defined in PostedDataMethods
  191 + */
  192 + public function getPostedDataMethod()
  193 + {
  194 + return $this->postedDataMethod;
  195 + }
  196 +
  197 + /**
  198 + * Sets the posted data method to POST
  199 + *
  200 + * @return static
  201 + */
  202 + public function expectsPostData()
  203 + {
  204 + $this->postedDataMethod(PostedDataMethods::POST);
  205 + return $this;
  206 + }
  207 +
  208 + /**
  209 + * @param string $method One of the method constants defined in PostedDataMethods
  210 + *
  211 + * @return static
  212 + */
  213 + public function postedDataMethod($method)
  214 + {
  215 + $this->postedDataMethod = $method;
  216 + return $this;
  217 + }
  218 +
  219 + /**
  220 + * Sets the posted data method to JSON_BODY
  221 + *
  222 + * @return static
  223 + */
  224 + public function expectsJsonData()
  225 + {
  226 + $this->postedDataMethod(PostedDataMethods::JSON_BODY);
  227 + return $this;
  228 + }
  229 +
  230 + /**
  231 + * Allows access to this collection for role with the given names. This can be overwritten on the Endpoint level.
  232 + *
  233 + * @param ...array $roleNames Names of the roles to allow
  234 + *
  235 + * @return static
  236 + */
  237 + public function allow()
  238 + {
  239 + $roleNames = func_get_args();
  240 +
  241 + // Flatten array to allow array inputs
  242 + $roleNames = Core::array_flatten($roleNames);
  243 +
  244 + foreach ($roleNames as $role) {
  245 +
  246 + if (!in_array($role, $this->allowedRoles)) {
  247 + $this->allowedRoles[] = $role;
  248 + }
  249 + }
  250 +
  251 + return $this;
  252 + }
  253 +
  254 + /**
  255 + * @return string[] Array of allowed role-names
  256 + */
  257 + public function getAllowedRoles()
  258 + {
  259 + return $this->allowedRoles;
  260 + }
  261 +
  262 + /***
  263 + * Denies access to this collection for role with the given names. This can be overwritten on the Endpoint level.
  264 + *
  265 + * @param ...array $roleNames Names of the roles to deny
  266 + *
  267 + * @return $this
  268 + */
  269 + public function deny()
  270 + {
  271 + $roleNames = func_get_args();
  272 +
  273 + // Flatten array to allow array inputs
  274 + $roleNames = Core::array_flatten($roleNames);
  275 +
  276 + foreach ($roleNames as $role) {
  277 +
  278 + if (!in_array($role, $this->deniedRoles)) {
  279 + $this->deniedRoles[] = $role;
  280 + }
  281 + }
  282 +
  283 + return $this;
  284 + }
  285 +
  286 + /**
  287 + * @return string[] Array of denied role-names
  288 + */
  289 + public function getDeniedRoles()
  290 + {
  291 + return $this->deniedRoles;
  292 + }
  293 +
  294 + public function getAclResources()
  295 + {
  296 + $apiEndpointIdentifiers = array_map(function (ExtendedApiEndpoint $apiEndpoint) {
  297 + return $apiEndpoint->getIdentifier();
  298 + }, $this->endpointsByName);
  299 +
  300 + return [
  301 + [new \Phalcon\Acl\Resource($this->getIdentifier(), $this->getName()), $apiEndpointIdentifiers]
  302 + ];
  303 + }
  304 +
  305 + /**
  306 + * @return string|null Name of the collection
  307 + */
  308 + public function getName()
  309 + {
  310 + return $this->name;
  311 + }
  312 +
  313 + public function getAclRules(array $roles)
  314 + {
  315 + $allowedResponse = [];
  316 + $deniedResponse = [];
  317 +
  318 + $defaultAllowedRoles = $this->allowedRoles;
  319 + $defaultDeniedRoles = $this->deniedRoles;
  320 +
  321 + foreach ($roles as $role) {
  322 +
  323 + /** @var ExtendedApiEndpoint $apiEndpoint */
  324 + foreach ($this->endpointsByName as $apiEndpoint) {
  325 +
  326 + $rule = null;
  327 +
  328 + if (in_array($role, $defaultAllowedRoles)) {
  329 + $rule = true;
  330 + }
  331 +
  332 + if (in_array($role, $defaultDeniedRoles)) {
  333 + $rule = false;
  334 + }
  335 +
  336 + if (in_array($role, $apiEndpoint->getAllowedRoles())) {
  337 + $rule = true;
  338 + }
  339 +
  340 + if (in_array($role, $apiEndpoint->getDeniedRoles())) {
  341 + $rule = false;
  342 + }
  343 +
  344 + if ($rule === true) {
  345 + $allowedResponse[] = [$role, $this->getIdentifier(), $apiEndpoint->getIdentifier()];
  346 + }
  347 +
  348 + if ($rule === false) {
  349 + $deniedResponse[] = [$role, $this->getIdentifier(), $apiEndpoint->getIdentifier()];
  350 + }
  351 + }
  352 + }
  353 +
  354 + return [
  355 + Acl::ALLOW => $allowedResponse,
  356 + Acl::DENY => $deniedResponse
  357 + ];
  358 + }
  359 +}
... ...
app/library/App/Mvc/ExtendedApiResource.php
... ... @@ -2,8 +2,6 @@
2 2  
3 3 namespace App\Mvc;
4 4  
5   -use App\Mvc\ExtendedApiCollection;
6   -use App\Mvc\ExtendedApiEndpoint;
7 5 use Phalcon\Di;
8 6 use Phalcon\Mvc\Micro\CollectionInterface;
9 7 use PhalconApi\Acl\MountableInterface;
... ... @@ -11,7 +9,7 @@ use PhalconRest\Constants\Services;
11 9 use PhalconRest\Mvc\Controllers\CrudResourceController;
12 10 use PhalconRest\Transformers\ModelTransformer;
13 11  
14   -class ExtendedApiResource extends ExtendedApiCollection implements MountableInterface, CollectionInterface
  12 +class ExtendedApiResource extends ExtendedApiCollection implements MountableInterface, CollectionInterface
15 13 {
16 14 protected $model;
17 15 protected $transformer;
... ...