<?php
/**
* @author AlexanderC
*/
require __DIR__ . '/../autoloader.php';
use PStorage\AModel;
use PStorage\Storage\DefaultClient;
use PStorage\Storage\Drivers\FileSystemDriver;
use PStorage\Storage\Client;
use PStorage\Storage\Table;
use PStorage\Helpers\Paginator;
/**
* Each model should extend AModel class
* to get it working
*/
class Post extends AModel
{
/**
* This method result would be used for defining
* table structure (aka scheme)
* [field aka property]
*
* self::PK - means primary key definition.
* This value gets increasing and used for fast entries look up's.
* This is pretty same as the Primary Key in Sql engine
*
* self::ONE - means that the field is represented by an single value
* self::MANY - means that the field is represented by an array of values.
* This is important when you have to search an single value from that array.
*
* self::REQUIRED - means that the field should not be empty when persisting
* self::UNIQUE - means that the field would be checked for duplicates in the table,
* and an exception would be thrown if so (aka Constrain violation in Sql engines)
*
* @return array
*/
protected function definition()
{
return [
'id' => self::PK, // self::UNIQUE by default
'title' => self::ONE | self::REQUIRED,
'text' => self::ONE | self::REQUIRED,
'tags' => self::MANY | self::REQUIRED,
'slug' => self::ONE | self::REQUIRED | self::UNIQUE,
'old_id' => self::ONE | self::UNIQUE
];
}
/**
* Behaviours are classes located at PStorage\Model\Behaviors namespace
* that extends PStorage\Model\Behaviors\ABehavior abstract class.
* We can define 2 kind of behaviours: Pre and Post persist.
*
* For example check Slugable Behaviour that will generate unique slugs
* for title field before persisting into DB
*
* Note: the key in returned array should be first part of behaviour class names,
* for example slugable will be transformed into Slugable and than added
* an Behaviour suffix. After manipulations we will get SlugableBehaviour class name.
*
* @return array
*/
protected function behaviors()
{
return [
'slugable' => [
'property' => 'title'
]
];
}
/**
* Comparators are used for managing advanced range queries on
* some fields. You can define you comparator by simple extending
* PStorage\Model\Comparators\AComparator class.
* The key in this array means field name and the value is the
* instance of comparator class of the first part of this, but in
* the last case comparator itself should be located in PStorage\Model\Comparators
* namespace (number -> NumberComparator).
*
* Note that comparator method is pretty same that an callback for
* usort or uksort functions in native PHP.
*
* If you define this for an field you are able to perform 3 more
* search operations on that fields.
*
* ADDITIONAL METHODS ALLOWED:
*
* Find rows with field values located between $offset and $property
* - public function findRangeOfComparable($offset, $limit, $property, Client $client = null)
*
* Find rows with field values greater than given $property
* - public function findGreaterOfComparable($value, $property, Client $client = null)
*
* Find rows with field values less than given $property
* - public function findLessOfComparable($value, $property, Client $client = null)
*
* ($property aka field)
*
* @return array
*/
protected function comparators()
{
return [
'old_id' => self::PROPERTY_NUMBER_COMPARATOR /* "number" */
];
}
/**
* This hook is called before persisting data
*
* @return void
*/
protected function prePersist()
{
// THIS IS REQUIRED!
parent::prePersist();
// do whatever you want...
}
/**
* This hook is called after persisting data
*
* @return void
*/
protected function postPersist()
{
// THIS IS REQUIRED!
parent::postPersist();
// do whatever you want...
}
}
// -------------------------------------------------------- //
/**
* Creating a new connection is pretty simple.
* You have to set default client that would be used to persist
* data. In any case you have ability to change it for each
* method called.
*
* FileSystemDriver- means that DB files would be stored locally in
* `__DIR__ . "/db"` folder passed as first argument
*
* Default serializer used is native PHP serialize/unserialize
* Another drivers can be found in PStorage\Storage\Serialization\Driver
* namespace and defined by passing instance of that as the second argument
* to the Client class
*/
DefaultClient::getInstance(new Client(new FileSystemDriver(__DIR__ . "/db")/* , Serializer... */));
// -------------------------------------------------------- //
// Creating a new post is pretty simple
$post = new Post();
$post->setTitle('New title');
$post->setText('Lorem ipsum dolor sit amet...');
$post->setTags([
'tag1', 'tag2', 'testtag'
]);
$post->setOld_id(10);
try {
$postId = $post->save();
} catch (\Exception $e) {
exit("Unable to add given post");
}
// -------------------------------------------------------- //
// So we can retrieve this post later, by id
$post = (new Post())->findOneById($postId);
if(false === $post) {
exit("Hey, missing post with id #{$postId}");
}
// we ca also change something here and save after
$post->setTitle('Awesome title');
try {
$post->save();
} catch (\Exception $e) {
exit("Unable to save given post");
}
// also we can easily delete it...
try {
$post->delete();
} catch (\Exception $e) {
exit("Unable to delete given post");
}
// -------------------------------------------------------- //
// Here is a list of operations that can be performed on top of the model/* \PStorage\Collection */
// Find all rows in the table
/* \PStorage\Collection */ $post->findAll();
// Count all rows in the table
/* integer */ $post->countAll();
// Find all rows using filters (match all applied)
/* \PStorage\Collection */ $post->findBy(['title' => 'New title']);
// Count all rows using filters (match all applied)
/* integer */ $post->countBy(['title' => 'New title']);
// Find first row using filters (match all applied)
/* AModel */ $post->findOneBy(['title' => 'New title']);
// NOTE: last 3 methods can be applied more verbose thanks to magic methods (__call)
// So you can just do something like:
/* AModel */ $post->findOneByTitleAndTags('New title', 'testtag');
// We can get a range of rows for the primary key (find rows with ids starting with 1 limit 10 [first ten entries])
/* \PStorage\Collection */ $post->findRangeByPrimaryKey(1, 10);
// NOTE: Do not forget about special methods for any comparable field
// for more details see "protected function comparators()" method doc block
// -------------------------------------------------------- //
// For paginating entries we ca use helper class
// following means: show 10 entries staring with id 50
$paginator = new Paginator($post, 50, 10);
foreach(/* \PStorage\Collection */ $paginator->getEntries() as $entry) {
echo "entry #{$entry->getId()}\n";
}
// -------------------------------------------------------- //
// We can se result order by simple using following
$post->getTable()->setResultOrder(Table::ORDER_ASC /* Table::ORDER_DESC */);
|