Releases: phproberto/joomla-entity
Version 2.0.0 - Stable
Index
- How to install / upgrade.
- Backward compatibility breaks.
2.1. New installation folder.
2.2. New entities folder. - New Features.
3.1. New MVC.
3.2. HasMailer trait.
3.3. CreateRootCategory command.
3.4. CreateRootAsset command.
3.5. Default Access for Articles.
3.6. New helper to deal with namespaces.
3.7. Entity Defaults.
3.8. CreateUncategorisedCategory command.
3.9. HasSingleton trait.
3.10. Predefined user groups classes.
3.11. Predefined view levels classes.
3.12. New ArrayHelper.
3.13. New Request class.
3.14. New RouteGenerator class.
3.15. New HasLinks class.
3.16. New JSONResponse class.
3.17. DatabaseSearcher improvements.
1. How to install / upgrade
Download joomla-entity-v2.0.0.zip an install through Joomla! Extension Manager.
2. Backward compatibility breaks
2.1. New installation folder.
Now the library uses the namespaced library system. This means that the library is installed in:
/libraries/phproberto/joomla_entity
instead of :
/libraries/joomla_entity
This ensures that no collisions will happen with other solutions and also solves the bug that prevented the library from being loaded through JLoader
. Before you needed to include the library like:
require_once JPATH_LIBRARIES . '/joomla_entity/library.php';
Now the library should be included like:
JLoader::import('phproberto.joomla_entity.library');
2.2. New entities folder.
This is not strictly a B/C change because I kept old entities in their original places but you should start loading entities from their new folder.
Before entities were directly stored in the root "extension" folder:
src/Content
and now they are stored in their own specific folder which makes them easier to find manage and keeps structure cleaner:
src/Content/Entity
Not all the entities are now in this folder and this is why this change is introduced in a B/C way. All the entities will get moved to their Entity folders and v3.x will remove support for old entity locations. All the new entities will be generated also in the Entity folders.
3. New Features
3.1. New MVC.
Te ease the integration with components now Joomla Entity provides a full set of methods to create an API for your components easily.
Do you need to a controller with a basic CRUD? You only have to integrate these traits:
- HasEntityGet - Get a single entity data with
ajaxEntityGet()
method. Example:task=article.ajaxEntityGet
. You also havejsonEntityGet()
which is the same but doesn't validate that the request is sent through AJAX. - HasEntityCreate - Create a single entity
ajaxEntityCreate()
method. Example call:task=article.ajaxEntityCreate
. - HasEntityUpdate - Edit a single entity
ajaxEntityUpdate()
method. Example call:task=article.ajaxEntityUpdate
. - HasEntityDelete - Edit a single entity
ajaxEntityDelete()
method. Example call:task=article.ajaxEntityDelete
.
All those traits require that tell the controller which entity is associated. The easiest way is done also through a trait HasAssociatedEntity
.
So a full CRUD for articles can be done like:
use Phproberto\Joomla\Entity\Contracts\AssociatedEntity;
use Phproberto\Joomla\Entity\MVC\Controller\Traits\HasAssociatedEntity;
use Phproberto\Joomla\Entity\MVC\Controller\Traits\HasEntityCreate;
use Phproberto\Joomla\Entity\MVC\Controller\Traits\HasEntityDelete;
use Phproberto\Joomla\Entity\MVC\Controller\Traits\HasEntityGet;
use Phproberto\Joomla\Entity\MVC\Controller\Traits\HasEntityUpdate;
class Phproberto_ContentControllerArticle extends FormController implements AssociatedEntity
{
use HasAssociatedEntity, HasEntityCreate, HasEntityDelete, HasEntityGet, HasEntityUpdate;
/**
* Retrieve the associated entity class.
*
* @return string
*/
public function entityClass()
{
return Article::class;
}
}
And you already have an API for your extension.
3.2. HasMailer trait.
There are some cases where we need to send mails within classes. Now Joomla Entity provides the HasMailer
trait that can be used like:
use Phproberto\Joomla\Entity\Traits\HasMailer;
class PlgPhproberto_NotificationSomeEvent extends BasePlugin
{
use HasMailer;
protected function onSomeEvent()
{
$recipients = [
'[email protected]',
'[email protected]'
];
$subject = 'Hello world!';
$body = 'This is a <strong>sample message</strong>';
$this->sendMail($recipients, $subject, $body);
}
}
3.3. CreateRootCategory command.
In some cases like new installations or tests environments we need the root category to be created. Now Joomla entity includes a command for it:
use Phproberto\Joomla\Entity\Categories\Command\CreateRootCategory;
$rootCategory = CreateRootCategory::instance()->execute();
It also provides a way to transparently create the root category if not present:
use Phproberto\Joomla\Entity\Categories\Category;
// This will load the root category if present or create it if it does not exist
$rootCategory = Category::root();
3.4. CreateRootAsset command.
Exactly like the root category Joomla Entity now provides a method to create the root asset.
use Phproberto\Joomla\Entity\Core\Command\CreateRootAsset;
$rootAsset = CreateRootAsset::instance()->execute();
and a way to create it transparently if it does not exist:
use Phproberto\Joomla\Entity\Core\Entity\Asset;
// This will load the root asset if present or create it if it does not exist
$rootAsset = Asset::root();
3.5. Default Access for Articles.
Before we needed to explicitly declare the access associated to any new article like:
$article = Article::create(
[
'title' => 'My article',
'access' => PublicViewLevel::instanceOrCreate()->id()
]
);
Now you don't need to specify the access
view level if it's the Public
view level:
$article = Article::create(
[
'title' => 'My article'
]
);
3.6. New helper to deal with namespaces.
use Phproberto\Joomla\Entity\Helper\ClassName;
// Check if a class is in a namespace
if (ClassName::inNamespace($class))
{
// Do something
}
// Retrieve the class without the namespace. Returns Article for Phproberto\Joomla\Entity\Content\Entity\Article
$name = ClassName::withoutNamespace($class);
// Retrieve the parts of the class namespace
// Will return an array like: ['Phproberto', 'Joomla', 'Entity', 'Content', 'Entity']
$parts = ClassName::namespaceParts($class);
// Return the parent namespace of a class
// Will return something like for Phproberto\Joomla\Entity\Content for a class like Phproberto\Joomla\Entity\Content\Entity\Article
$parentNamespace = ClassName::parentNamespace($class);
3.7. Entity Defaults.
Now you can provide default values with your entities so only strictly required data is sent when trying to create an entity. Things like default access group, etc. will never be required again.
Defaults are only applied to an entity when it's saved for the first time (when creating it).
Let's use as example default applied to categoriesd (src/Categories/Category.php
):
/**
* Default data for new instances.
*
* @return []
*
* @since __DEPLOY_VERSION__
*/
public function defaults()
{
$parent = $this->hasParent() ? $this->parent() : self::root();
return [
'extension' => static::$extension,
CoreColumn::ACCESS => (int) $parent->get(CoreColumn::ACCESS),
CoreColumn::PARENT => $parent->id(),
CoreColumn::STATE => (int) $parent->get(CoreColumn::STATE)
];
}
As you can see new categories inherit access from their parent category and they are (if not specified) child categories of the root category.
3.8. CreateUncategorisedCategory command.
com_content usually provides a base
Uncategorised` category that is used to assign it to articles with no specific category assigned. This command creates it for us.
use Phproberto\Joomla\Entity\Content\Command\CreateUncategorisedCategory;
$uncategorisedCategory = CreateUncategorisedCategory::instance()->execute();
// Transparently create the uncategorised category if it does not exist:
use Phproberto\Joomla\Entity\Content\Entity\Category;
$uncategorisedCategory = Category::uncategorised();
3.9. HasSingleton trait.
This can be used for classes where a single instance should be used.
3.10. Predefined user groups classes.
There is now a list of predefined user groups to ease dealing with core stuff:
// Retrieves the Public user group or...
Version 1.8.0 - Stable
Index
- How to install / upgrade
- New Features
2.1. hasEmptyDate(). Check if an entity date property is empty
2.2. showNotEmptyDate(). Show a date when it's not empty
2.3. Commands
1. How to install / upgrade
Download joomla-entity-v1.8.0.zip an install through Joomla! Extension Manager.
2. New Features
2.1. hasEmptyDate(). Check if an entity date property is empty
This function is useful when you only want to do something with a date if it's not empty. It covers all the possible empty values Joomla may find:
- null, '', '0', '0000-00-00', '0000-00-00 00:00:00', '1971-01-01', '1971-01-01 00:00:00'
use Phproberto\Joomla\Entity\Content\Article;
$article = Article::find(2);
if (!$article->hasEmptyDate('modified'))
{
echo $article->showDate('modified', 'Y-m-d H:i:s');
}
2.2. showNotEmptyDate(). Show a date when it's not empty
This function allows to easily show a date when it's not empty and provide a default value to show when a date is empty.
use Phproberto\Joomla\Entity\Content\Article;
$article = Article::find(2);
echo '<span class="article-date">';
echo $article->showNotEmptyDate('modified', 'Y-m-d H:i:s', ['default' => 'Not available']);
echo '</span>';
2.3. Commands.
From this version this library will try to provide common commands required by developers to deal with files, database, entities, etc. It tries to apply the same concept behind entities. Provide a developer friendly interface to access commont tasks.
Examples:
// Drop a database table
use Phproberto\Joomla\Entity\Command\Database\DropTable;
DropTable::instance(['#__phproberto_table'])->execute();
// Empty a database table
use Phproberto\Joomla\Entity\Command\Database\EmptyTable;
EmptyTable::instance(['#__phproberto_table'])->execute();
// Execute an SQL file
use Phproberto\Joomla\Entity\Command\Database\ExecuteSQLFile;
ExecuteSQLFile::instance([__DIR__ . '/my-file.sql'])->execute();
// Delete a folder recursively
use Phproberto\Joomla\Entity\Command\FileSystem\DeleteFolderRecursively;
DeleteFolderRecursively::instance([__DIR__ . '/my-folder'])->execute();
Check Documentation for detailed information and usage examples.
Version 1.7.2 - Stable
How to install / upgrade
Download joomla-entity-v1.7.2.zip an install through Joomla! Extension Manager.
Bug fixes
Data lost when saving entity
Updating an entity with something like:
$category = new Category;
$category->bind(['id' => 23, 'title' => 'My Category', 'extension' => 'com_content']);
$category->save();
Was overwriting any data already saved in Category 23. Now all the entities load previous data before saving them with the new data.
Version 1.7.0 - Stable
How to install / upgrade
Download joomla-entity-v1.7.0.zip an install through Joomla! Extension Manager.
New Features
New fitler.active_language
filter for ArticleSearch
& CategorySearch
It allows to show content only from the active language.
use Phproberto\Joomla\Entity\Content\Search\ArticleSearch;
use Phproberto\Joomla\Entity\Categories\Search\CategorySearch;
// Return only articles assigned to the active language
$articles = ArticleSearch::instance(['filter.active_language' => true])->search();
// Return only categories assigned to the active language
$categories = CategorySearch::instance(['filter.active_language' => true])->search();
New IsNullOrPositiveInteger
validation rule.
This rule will check if a value is null or a positive integer. Useful to test foreign keys values.
use Phproberto\Joomla\Entity\Validation\Rule\IsNullOrPositiveInteger;
$rule = new IsNullOrPositiveInteger;
// True
var_dump($rule->passes(1));
var_dump($rule->passes('1'));
var_dump($rule->passes(1.0));
var_dump($rule->passes(null));
// False
var_dump($rule->passes('test-string'));
var_dump($rule->passes(''));
var_dump($rule->passes(1.1));
New IsZeroOrPositiveInteger
validation rule.
This new rule will return true when a value is zero or a positive integer (1,2,3,etc.)
use Phproberto\Joomla\Entity\Validation\Rule\IsZeroOrPositiveInteger;
$rule = new IsZeroOrPositiveInteger;
// True
var_dump($rule->passes(1));
var_dump($rule->passes('1'));
var_dump($rule->passes(1.0));
var_dump($rule->passes(0));
// False
var_dump($rule->passes('test-string'));
var_dump($rule->passes(''));
var_dump($rule->passes(1.1));
New filter.not_author_id
filter for ArticleSearch
Allows to show articles created by a different user. This can be useful to show related articles or to show an user articles he/she may be interested in.
use Phproberto\Joomla\Entity\Users\User;
use Phproberto\Joomla\Entity\Content\Search\ArticleSearch;
$user = User::active();
// If the active user is not a guest load articles not created by him/her
$articles = $user->isGuest() ? [] : ArticleSearch::instance(['filter.not_author_id' => $user->id()])->search();
New filter.not_language
filter for ArticleSearch
.
It allows to search articles with a language different than the specified.
use Phproberto\Joomla\Entity\Content\Search\ArticleSearch;
// Search articles that are not written in english
$articles = ArticleSearch::instance(['filter.not_language' => 'en-GB'])->search();
New CategoryValidator
assigned to Category
entity.
It prevents categories from being saved without the minimum required or valid data. You can see all the assigned validation rules here
use Phproberto\Joomla\Entity\Categories\Category;
$category = new Category;
$category->bind(['title' => 'My category']);
try
{
$category->save();
}
catch (\Exception $e)
{
/**
* This will show something like:
*
* Validation failed trying to create `category`:
* `category` is not valid:
* * `extension` does not pass `Not empty extension` validation rule
*/
echo $e->getMessage();
}
// This will add the missing extension and allow to save without errors;
$category->assign('extension', 'com_content');
try
{
$category->save();
}
catch (\Exception $e)
{
// No exception should happen
}
New TagSearch
class.
Use this class to search for tags.
use Phproberto\Joomla\Entity\Tags\Search\TagSearch;
// Only return tags with specific view level
$tags = TagSearch::instance(['filter.access' => 1])->search();
// Only return tags available for the active language
$tags = TagSearch::instance(['filter.active_language' => true])->search();
// Only return tags available for the active user
$tags = TagSearch::instance(['filter.active_user_access' => true])->search();
// Only return tags with specified ancestor
$tags = TagSearch::instance(['filter.ancestor_id' => 12])->search();
// Only return tags assigned to a specified content_item. This is only useful combined with filter.content_type_alias because 2 different content types can have the same id.
$tags = TagSearch::instance(['filter.content_item_id' => 14])->search();
// Only return tags from the specifiec content type
$tags = TagSearch::instance(['filter.content_type_alias' => 'com_content.article'])->search();
// Only return tags that are ascendants of the specified tag
$tags = TagSearch::instance(['filter.descendant_id' => 14])->search();
// Only return tags with the specified id/ids
$tags = TagSearch::instance(['filter.id' => [12,14]])->search();
// Only return tags with the specified language/languages
$tags = TagSearch::instance(['filter.language' => ['en-GB','*']])->search();
// Only return tags with the specified level/levels
$tags = TagSearch::instance(['filter.level' => 2])->search();
// Only return tags with ids distinct to the specified
$tags = TagSearch::instance(['filter.not_id' => [1,2]])->search();
// Only return tags that are direct children of specfied tags
$tags = TagSearch::instance(['filter.parent_id' => 1])->search();
// Only return published tags
$tags = TagSearch::instance(['filter.published' => 1])->search();
// Only return unpublished tags
$tags = TagSearch::instance(['filter.published' => 0])->search();
// Only return tags with a title, alias or path containing specified string
$tags = TagSearch::instance(['filter.search' => 'cars'])->search();
New HasTags::searchTags()
method to easily search within an entity tags.
use Phproberto\Joomla\Entity\Content\Article;
$article = Article::find(1);
// You can pass filters to the search as if you were directly using an TagSearch instance
$tags = $article->searchTags(['filter.published' => 1, 'list.limit' => 5]);
foreach ($tags as $tag)
{
echo 'Article `' . $article->get('title') . '` has ' . $tag->get('title) . ' tag';
}
New Category::searchArticles()
method to easily search within an category articles.
use Phproberto\Joomla\Entity\Content\Category;
$category = Category::find(1);
// You can pass filters to the search as if you were directly using an ArticleSearch instance
$articles = $article->searchTags(['filter.active_language' => true, 'list.limit' => 5]);
foreach ($articles as $article)
{
echo 'Category `' . $category->get('title') . '` has ' . $article->get('title) . ' article';
}
New HasTags::removeAllTags()
method
This method can be used to remove all the tags assigned to an entity.
use Phproberto\Joomla\Entity\Content\Article;
// This will unassign all the article tags
Article::find(1)->removeAllTags();
Version 1.6.0 - Stable
How to install / upgrade
Download joomla-entity-v1.6.0.zip an install through Joomla! Extension Manager.
Bug fixes
User::loadFromData() now supports multiple columns
See #24
Now you can use User
entity to load users based on specific column values as with any other entity:
use Phproberto\Joomla\Entity\Users\User;
// Try to load user with specific email
$user = User::loadFromData(['email' => '[email protected]']);
if (false === $user)
{
// User was not found
}
// Show user name
echo $user->get('name');
New Features
Saving an user through User entity triggers onUserAfterSave
event.
Before this release a used saved through User entity was not triggering onUserAfterSave
event limiting Joomla flexibility. Now it triggers exactly the same events than a user created through Joomla\CMS\User\User
.
New filters for CategorySearch
use Phproberto\Joomla\Entity\Categories\Search\CategorySearch;
// This won't return non-viewable categories
$categories = CategorySearch::instance(['filter.active_user_access' => true])->search();
// Only show categories with specified language
$categories = CategorySearch::instance(['filter.language' => 'es-ES'])->search();
New article search class
You can now easily search articles using ArticleSearch
class.
use Phproberto\Joomla\Entity\Content\Search\ArticleSearch;
// Search articles containing Joomla in their title or alias
$articles = ArticleSearch::instance(['filter.search' => 'Joomla'])->search();
// Search articles created by specific user
$articles = ArticleSearch::instance(['filter.author_id' => 84])->search();
// All the filters support array values. Search articles created by 2 users
$articles = ArticleSearch::instance(['filter.author_id' => [84, 86]])->search();
// Search articles edited by user
$articles = ArticleSearch::instance(['filter.editor_id' => 84])->search();
// Search articles with specified ids
$articles = ArticleSearch::instance(['filter.id' => [14, 15]])->search();
// Search articles with ids not in a specified array
$articles = ArticleSearch::instance(['filter.not_id' => [14, 15]])->search();
// Only show articles viewable by the active user
$articles = ArticleSearch::instance(['filter.active_user_access' => true])->search();
// Only show articles in specified view levels
$articles = ArticleSearch::instance(['filter.access' => [1, 5]])->search();
// Only show articles in specified categories
$articles = ArticleSearch::instance(['filter.category_id' => [12, 13]])->search();
// Only show articles from categories different to the specified
$articles = ArticleSearch::instance(['filter.not_category_id' => [12, 13]])->search();
// Only show featured articles
$articles = ArticleSearch::instance(['filter.featured' => 1])->search();
// Only show not featured articles
$articles = ArticleSearch::instance(['filter.featured' => 0])->search();
// Only show articles from specified language
$articles = ArticleSearch::instance(['filter.language' => 'en-GB'])->search();
// Only show articles in specified state(s)
$articles = ArticleSearch::instance(['filter.state' => [0,1]])->search();
// Only show articles not in specified state(s)
$articles = ArticleSearch::instance(['filter.not_state' => [1]])->search();
// Only show articles with specified tags
$articles = ArticleSearch::instance(['filter.tag' => [1]])->search();
// Of course you can combine all the filters.
$articles = ArticleSearch::instance(
[
'filter.active_user_access' => true,
'filter.state' => 1,
'filter.category_id' => 5
]
)->search();
New Content CategorySearch
Class Phproberto\Joomla\Entity\Content\Search\CategorySearch
supports all the filters from Phproberto\Joomla\Entity\Categories\Search\CategorySearch
but only returns categories used by com_content
.
It also supports tag filtering.
use Phproberto\Joomla\Entity\Content\Search\CategorySearch;
// Only return categories with tags with ids 1 or 2 assigned
$categories = CategorySearch::instance(['filter.tag' => [1,2]])->search();
New user search
You can now easily search articles using UserSearch
class.
use Phproberto\Joomla\Entity\Users\Search\UserSearch;
// Only return blocked users
$users = UserSearch::instance(['filter.blocked' => 1])->search();
// Only return not blocked users
$users = UserSearch::instance(['filter.blocked' => 0])->search();
// Only return users assigned to specified groups
$users = UserSearch::instance(['filter.group' => [1,8]])->search();
// Only return users not assigned to specified groups
$users = UserSearch::instance(['filter.group' => 2])->search();
// Only return users with 'roberto' in name, username or email
$users = UserSearch::instance(['filter.search' => 'roberto'])->search();
Version 1.5.0 - Stable
How to install / upgrade
Download joomla-entity-v1.5.0.zip an install through Joomla! Extension Manager.
Bug fixes
Nested entities not saving correct lft/rgt values
When adding or editing a category (or any other nested entity) we were not updating its location in the nested tree. Now they are saved correctly.
New Features
New method to easily change user password
// Change user password with one line!
User::find(42)->changePassword('myNewPassword');
New search filter for CategorySearcher
use Phproberto\Joomla\Entity\Categories\CategorySearcher;
// Search all the categories with title, alias, path or extension like `roberto`
$categories = CategorySearcher::instance(['filter.search' => 'roberto'])->search();
New level filter for CategorySearcher
use Phproberto\Joomla\Entity\Categories\CategorySearcher;
// Search all the categories with level equal to 1
$categories = CategorySearcher::instance(['filter.level' => 1])->search();
// Search all the categories with level equal to 1 or 2
$categories = CategorySearcher::instance(['filter.level' => [1,2]])->search();
Version 1.4.1 - Stable
How to install / upgrade
Download joomla-entity-v1.4.1.zip an install through Joomla! Extension Manager.
New Features
New Module entity
use Phproberto\Joomla\Entity\Core\Module;
$module = Module::find(1);
// Do something if module is published
if ($module->isPublished())
{
echo 'Module ' . $module->get('title') . ' is published!';
}
// Module entity implements HasParams trait so you can easily access params like this
if ('mainmenu' === $module->param('menutype'))
{
echo 'Module ' . $module->get('title') . ' is publishing Main Menu';
}
// Module entity implements HasClient
if ($module->client()->isSite())
{
echo 'Module ' . $module->get('title') . ' is a frontend module';
}
// Retrieve the menu items where the module is available
echo 'Module ' . $module->get('title') . ' is published in menu items: ' . implode(',', $module->menusIds());
New HasLevel trait
This trait is designed to access level
columns in entities like categories or other nested entites but you can use it for any entity with a column storing a numeric value you need to compare against other entities.
use Phproberto\Joomla\Entity\Content\Category;
$category = Category::find(23);
if ($category->hasLevel(0))
{
echo 'Category ' . $category->get('title') . ' is a root category.';
}
else
{
echo 'Category ' . $category->get('title') . ' is a level ' . $category->level() . ' category.';
}
if ($category->hasLevelBetween(1,5))
{
echo 'Category ' . $category->get('title') . ' has a level between 1 and 5';
}
if ($category->hasLevelGreater(1))
{
echo 'Category ' . $category->get('title') . ' has a level greater than 1';
}
if ($category->hasLevelLower(6))
{
echo 'Category ' . $category->get('title') . ' has a level lower than 6';
}
New HasParent trait.
This trait is designed to access parent entities in nested entities but you can use it in any entity where you store a column pointing to a parent entity.
use Phproberto\Joomla\Entity\Content\Category;
$category = Category::find(23);
echo 'Category ' . $category->parent()->get('title') . ' is the parent category of ' . $category->get('title');
// You can access parent id without loading it through parentId()
$extensions = Category::find(20);
if ($extensions->id() === $category->parentId())
{
echo 'Extensions is the parent category of ' . $category->get('title');
}
New HasAncestors trait.
This trait is designed for entities using a nested structure like categories.
use Phproberto\Joomla\Entity\Content\Category;
$category = Category::find(23);
// Show the tree of ancestors for a category
foreach ($category->ancestors() as $ancestor)
{
// Avoid showing root level
if ($ancestor->hasLevel(0))
{
continue;
}
echo '<pre>';
echo str_repeat('--', $ancestor->level() - 1) . ' ' . $ancestor->id() . '.' . $ancestor->get('title');
echo '</pre>';
}
It will show something like:
14.Sample Data-Articles
-- 19.Joomla!
---- 20.Extensions
Mixing it with the power of collections you can do cool things:
// Check if a category is an ancestor
if ($category->ancestors()->has(20))
{
echo '<pre>Category ' . Category::find(20)->get('title') . ' is an ancestor of ' .$category->get('title') . '</pre>';
}
You can also search within ancestors!
// Searching ancestors without root category
echo '<h3>Not root ancestors</h3>';
foreach ($category->searchAncestors(['filter.ancestor_id' => 1]) as $ancestor)
{
echo '<pre>Category ' . $ancestor->get('title') . ' is an ancestor of ' . $category->get('title') . '</pre>';
}
// You can also apply custom ordering
echo '<h3>Not root ancestors ordered by title</h3>';
foreach ($category->searchAncestors(['filter.ancestor_id' => 1, 'list.ordering' => 'c.title']) as $ancestor)
{
echo '<pre>Category ' . $ancestor->get('title') . ' is an ancestor of ' . $category->get('title') . '</pre>';
}
// And custom ordering in custom direction
echo '<h3>Not root ancestors ordered by title descendently</h3>';
foreach ($category->searchAncestors(['filter.ancestor_id' => 1, 'list.ordering' => 'c.title', 'list.direction' => 'DESC']) as $ancestor)
{
echo '<pre>Category ' . $ancestor->get('title') . ' is an ancestor of ' . $category->get('title') . '</pre>';
}
New HasDescendants trait.
This trait is designed for entities using a nested structure like categories.
use Phproberto\Joomla\Entity\Content\Category;
$category = Category::find(23);
echo '<h3>Descendant categories of ' . $category->get('title') . '</h3>';
foreach ($category->descendants() as $descendant)
{
echo '<pre>';
echo str_repeat('--', $descendant->level() - 1) . ' ' . $descendant->id() . '.' . $descendant->get('title');
echo '</pre>';
}
It will show something like:
Descendant categories of Templates
-------- 69.Beez 20
-------- 70.Beez 5
-------- 68.Atomic
You can also use searchDescendants()
to perform custom filtering like explained in the HasAncestors
trait info.
Introducing searchers
This release starts to integrate the concept of searcher
which represents a class to find entities of X type. For example the CategorySearcher
searches data to feed entities of type Category
.
use Phproberto\Joomla\Entity\Categories\CategorySearcher;
// Search all the categories with access level equal to 2
$categories = CategorySearcher::instance(['filter.access' => 2, 'list.limit' => 0])->search();
// Search all the unpublished categories
$categories = CategorySearcher::instance(['filter.published' => 0, 'list.limit' => 0])->search();
// Search all the categories with a specific ancestor
$categories = CategorySearcher::instance(['filter.ancestor_id' => 20, 'list.limit' => 0])->search();
// Search all the categories with a specific descendant
$categories = CategorySearcher::instance(['filter.descendant_id' => 21, 'list.limit' => 0])->search();
There are a lot of things to add to the CategorySearcher
like filtering by level, language, search by title, etc. Feel free to contribute it or just wait until it's needed by someone else and contributed.
New Collection::fromData() method.
This method is a fast way to generate a collection from an array of data.
use Phproberto\Joomla\Entity\Collection;
use Phproberto\Joomla\Entity\Categories\CategorySearcher;
use Phproberto\Joomla\Entity\Content\Category;
$unpublishedCategories = Collection::fromData(
// Data
CategorySearcher::instance(['filter.published' => 0])->search(),
// Associated entity
Category::class
);
// Having a collection gives you some benefits over pure data because you have entities there and method to retrieve ids, etc.
echo 'Unpublished categories with ids: ' . implode(',', $unpublishedCategories->ids());
foreach ($unpublishedCategories as $category)
{
echo 'Category ' . $category->get('title') . ' is unpublished';
}
Version 1.4.0 - Stable
How to install / upgrade
Download joomla-entity-v1.4.0.zip an install through Joomla! Extension Manager.
New Features and bug fixes.
See v1.4.1. notes.
Version 1.3.0 - Stable
How to install / upgrade
Download joomla-entity-v1.3.0.zip an install through Joomla! Extension Manager.
New Features
- Fast method to retrieve user identifier for entities using
HasUser
trait.
// This entity uses the HasUser Trait
$entity = MyEntity::find(42);
// This will compare entity's ID with active user ID
if ($entity->hasUser() && User::active()->id() === $entity->userId())
{
echo 'Active user is entity user!';
}
- Methods to add user to one or more user groups:
$user = User::find(42);
// Add user to one user group
$user->addToUserGroup(5);
// Add user to multiple user groups
$user->addToUserGroups([5, 7]);
- Methods to remove user from one/multiple/all user groups:
$user = User::find(42);
// Remove user from one user group
$user->removeFromUserGroup(5);
// Remove user from multiple user groups
$user->removeFromUserGroups([5, 7]);
// Remove user from all his/her user groups
$user->removeFromAllUserGroups();
- Method to easily retrieve authorId() on entities implementing
HasAuthor
trait:
$entity = Article::find(3);
if ($entity->hasAuthor() && User::active()->id() === $entity->authorId())
{
echo 'You are the author of this article!';
}
- Method to easily retrieve editorId() on entities implementing
HasEditor
trait:
$entity = Article::find(3);
if ($entity->hasEditor() && User::active()->id() === $entity->editorId())
{
echo 'You are the editor of this article!';
}
Version 1.2.0 - Stable
How to install / upgrade
Download joomla-entity-v1.2.0.zip an install through Joomla! Extension Manager.
New Features
- New
loadFromData()
method to load entities by specified columns data:
$userGroup = UserGroup::loadFromData(['title' => 'Registered', 'parent_id' => 1]);
if ($userGroup->isLoaded())
{
echo $userGroup->get('title') . ' user groups exists!';
}
- New
delete()
method to easily delete entities:
Article::delete(23);
// A DeleteException will be thrown if something fails so at this point we are sure delete worked.
echo 'Article 23 was successfully deleted';
// Delete multiple articles passing an array
Article::delete([23, 24, 25]);
// Example catching exception
$msg = 'Article 23 was successfully deleted';
try
{
Article::delete(23);
}
catch (DeleteException $e)
{
$msg = $e->getMessage();
}
echo $msg;
- New FieldGroup entity:
$fieldGroup = FieldGroup::find(1);
foreach ($fieldGroup->fields() as $field)
{
echo 'Field `'. $field->get('title') . '` is in the field group `' . $fieldGroup->get('title') . '`';
}
- Now it's possible to check and retrieve field group from field entity:
$field = Field::find(1);
if ($field->hasFieldGroup())
{
echo 'Field `'. $field->get('title') . '` is in the field group `' . $field->fieldGroup()->get('title') . '`';
}
- Now it's possible to check if an entity has associated fields with
hasFields()
:
$article = Article::find(12);
if ($article->hasFields())
{
foreach ($article->fields() as $field)
{
// Do something
}
}
- New
VielLevel
entity:
$viewLevel = ViewLevel::find(1);
// This will echo something like: Public
echo $viewLevel->get('title');
// Check if a view level has user groups
if ($viewLevel->hasUserGroups())
{
// Do something
}
// Check if a view level has an user group
if ($viewLevel->hasUserGroup(1))
{
// Do something
}
- Now it's possible to retrieve user view levels:
$user = User::find(42);
// This returns a collection of ViewLevel entities
$viewLevels = $user->viewLevels();
// Check if user has view levels
if ($user->hasViewLevels())
{
// Do something
}
// Check if user has a specific view level
if ($user->hasViewLevel(1))
{
// Do something
}