Skip to content

Commit

Permalink
Merge pull request #1 from dreanmer/feature/criteria
Browse files Browse the repository at this point in the history
Adding Criterias to improve db queries usability
  • Loading branch information
magroski authored Oct 2, 2017
2 parents 99aaf0b + 9317b33 commit 9e1551d
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 19 deletions.
103 changes: 103 additions & 0 deletions Criteria.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php
/**
* Created by PhpStorm.
* User: Alexandre
* Date: 29/09/2017
* Time: 13:47
*/

namespace Frogg;

use Phalcon\Mvc\Model as PhalconModel;

/**
* Class Criteria
*
* default call criteria on model, example:
*
* public static function query(DiInterface $dependencyInjector = null)
* {
* return parent::query($dependencyInjector)->softDelete();
* }
*
* @package Frogg
* @method static addSoftDelete(string $column = 'deleted', int $activeValue = 0) add soft delete criteria to the query
* @method static removeSoftDelete() removes soft delete criteria from the criteriaQueue
*/
class Criteria extends PhalconModel\Criteria
{
private $modelCriterias = [];

/**
* removes soft deleted entries from the result.
*
* @param string $column
* @param int $activeValue
*
* @return PhalconModel\Criteria
* @internal param $add
*
*/
public function softDeleteCriteria($column = 'deleted', $activeValue = 0)
{
return $this->andWhere($column.'='.$activeValue);
}

/**
* alias to make more sense when calling it on query building.
*
* @return $this
*/
public function withDeleted()
{
return $this->removeSoftDelete();
}

public function execute()
{
$instance = $this;
foreach ($this->modelCriterias as $criteria => $value) {
$method = lcfirst($criteria).'Criteria';
$instance = $instance->$method(...$value);
}

return $instance->parentExecute();
}

public function getPhql()
{
return $this->createBuilder()->getPhql();
}

public function getQuery()
{
return $this->createBuilder()->getQuery();
}

public function getActiveCriterias()
{
return $this->modelCriterias;
}

private function parentExecute()
{
return parent::execute();
}

public function __call($name, $arguments)
{
if (strpos($name, 'add') !== false) {
$criteria = str_replace('add', '', $name);
$this->modelCriterias[$criteria] = $arguments;
} else if (strpos($name, 'remove') !== false) {
$criteria = str_replace('remove', '', $name);
if (isset($this->modelCriterias[$criteria])) {
unset($this->modelCriterias[$criteria]);
}
} else {
Throw new \Exception('Method '.$name.' does not exist.');
}

return $this;
}
}
46 changes: 27 additions & 19 deletions Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,33 @@
namespace Frogg;

use Frogg\Crypto\WT;
use Phalcon\Di;
use Phalcon\DiInterface;
use Phalcon\Mvc\Model as PhalconModel;

/**
* Class Model
* @package Frogg
*
* @method static static findFirstById(int $id)
/**
* Class Model
* @package Frogg
*
* @method static static findFirstById(int $id)
*/
class Model extends PhalconModel
{
/**
* @param DiInterface|null $dependencyInjector
*
* @return \Frogg\Criteria $criteria
*/
public static function query(DiInterface $dependencyInjector = null)
{
$class = '\\'.get_called_class().'Criteria';
/** @var \Frogg\Criteria $criteria */
$criteria = new $class();
$criteria->setDI($dependencyInjector ?? Di::getDefault());
$criteria->setModelName(get_called_class());

return $criteria;
}

public function columnMap()
{
Expand All @@ -30,24 +47,14 @@ public function columnMap()
return $columnMap;
}

/**
* @param string $attribute Name of the attribute that will be used to create a permalink
*
* @return string A permalink formatted string
*/
public function permalinkFor(string $attribute): string
public function permalinkFor($attribute)
{
$tmp = new Permalink($this->$attribute);

return $this->getNumeration($tmp->create());
}

/**
* @param array $values Values that will be used to create a permalink
*
* @return string A permalink formatted string
*/
public function permalinkForValues(array $values): string
public function permalinkForValues($values)
{
for ($i = 0; $i < count($values); $i++) {
$values[$i] = Permalink::createSlug($values[$i]);
Expand All @@ -57,7 +64,7 @@ public function permalinkForValues(array $values): string
return $this->getNumeration($value);
}

public function tokenId($key): string
public function tokenId($key)
{
return WT::encode(['id' => $this->id], $key);
}
Expand All @@ -69,7 +76,7 @@ public static function getByTokenId($token, $key)
return isset($data->id) ? static::findFirstById($data->id) : false;
}

private function getNumeration($slug): string
private function getNumeration($slug)
{
$resultset = $this->getReadConnection()->query("SELECT `permalink`
FROM `".$this->getSource()."`
Expand All @@ -89,3 +96,4 @@ private function getNumeration($slug): string
}

}

54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#### Model Criteria usage example:

```php
class ModelCriteria extends Frogg\Criteria
{
/**
* @return \Phalcon\Mvc\Model\Criteria
*/
public function ofUser($id)
{
return $this->where('user_id = '.$id);
}
}
```

```php
$result = Model::query()->ofUser(1)->where('x' > 'y')->execute();
```

#### Global Criteria usage example:

```php
class Model extends Frogg\Model
{
/**
* @return ModelCriteria
*/
public static function query(DiInterface $dependencyInjector = null)
{
return parent::query($dependencyInjector)->addSoftDelete();
}
}
```

```php
// this result applies softDelete for default, so all 'deleted = 1' results will be filtered
// (this filter is added at the end of the query)
$result = Model::query()->where('x' > 'y')->execute();

// but you can remove a global criteria calling removeCriteriaName
$resultWithDeleted = Model::query()->removeSoftDelete()->where('x' > 'y')->execute();
// or for this specific method, we have an alias
$resultWithDeleted = Model::query()->withDeleted()->where('x' > 'y')->execute();
```

#### Debugg tip

You can get some infos like:
```php
$builder = Model::query()->where('x' > 'y');
$phql = $builder->getPhql();
$buildedQuery = $builder->getQuery();
$criterias = $builder->getActiveCriterias();
```

0 comments on commit 9e1551d

Please sign in to comment.