Download the PHP package anexia/laravel-basemodel without Composer

On this page you can find all versions of the php package anexia/laravel-basemodel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-basemodel

Anexia BaseModel

A Laravel package used to provide extended basic functionality (filtering, sorting, pagination) to eloquent models.

1. Installation and configuration

Install the module via composer, therefore adapt the require part of your composer.json:

Now run

to add the packages source code to your /vendor directory and update the autoloading.

2. Usage

2.1. Models

Use the BaseModelInterface in combination with the BaseModelTrait in all models that are supposed to support the base functionality (filtering, sorting, pagination, ...).

2.2. Controllers

Use the BaseModelController to allow 'bulk actions' (create, update, delete) over multiple layers of object relations. It comes with the method 'editObjectContents' which expects a BaseModel (implementing the BaseModelInterface and using the BaseModelTrait) and the new properties (as array, as provided by a POST/PUT/PATCH request).

It uses the nested transactions* provided by the SubTransactionServiceProvider, which allows better control over the data on multiple related models at once.

3. Model Configuration Methods

The BaseModelInterface demands several internal configurations for each model, most of them can be empty by default (as many in the BaseModelTrait). But if need be, specific alterations of those configuration methods can make any model very self-sufficient in regards of validation, change behaviour and other aspects.

3.1. getUnmodifiable

expected result: array of unmodifiable properties

All properties returned by this function will be excluded from the BaseModelController's 'editObjectContents' method. Thus, those properties will not be automatically/bulk edited and must be set/changed explicitly.

3.2. getDefaults

expected result: array of the properties with their default values

If properties get values assigned within this method, the BaseModel constructor will automatically fill them on model instantiation (regardless of whether they are defined as $guarded or $fillable). They do not have to be set explicitly.

3.3. getDefaultSearch

expected result: array of properties that shall be searched by default whenever allExtended is called with 'search' parameters.

Those parameters can either be handed on method calling (setSearches and setOrSearches) or via a HTTP request (fetched via request()->all() and handled as $searches and $orSearches in the allExtended method). All properties returned by the getDefaultSearch function will be searched with the given sub string ('WHERE x LIKE "y"' SQL condition), the searches will be OR connected.

See section Searching for more details on the search behaviour.

3.4. getDefaultSorting

expected result: all properties plus the wanted direction that shall be sorted by default whenever allExtended is called.

See section Sorting for more details on the sorting behavior.

3.5. getRelationships

expected result: all properties that are associated with a related model class. possible input: boolean $list parameter

If $list is true, this method should return a simple array of all relation-properties plus their related class.

Example

If $list is false however, this method should return a more complex representation of the model's relations. It should then return a multi-array of 'one' and 'many' relations, according to the relation's nature. Furthermore should each relation property not only contain the related classes name, but also how the corresponding property on the related model is called (inverse side) and whether or not the relation is editable and nullable from the current model's side.

Example

Depending on the configuration of the model's relationships, the BaseModelController's 'editObjectContent' method will iterate through the related objects (and their relations, and their relations, etc.) and make changes (creation or update) on them.

3.6. getValidationRules

Should only be overwritten if you need special logic, otherwise these rules can be supplied with $validationRules.

expected result: all laravel validation rules (see https://laravel.com/docs/5.3/validation for details on the supported rules) that are associated with a related model class. possible input: boolean $checkCompletion parameter

If $checkCompletion is true, $validationRules will be prefixed with the required attribute.

If $checkCompletion is true, this method should return all properties with all their necessary validation rules.

If $checkCompletion is false however, the returned rules should support only partial presence of the editable properties, to support PATCH requests.

Example 1

Example 2

In the example above the 'required' rules do not get returned on $checkCompletion = false, since it is possible, that only the name of an existing post might be updated. If the 'required' rules applied, a request like

would result in an error with the information, that the fields 'type' and 'author_id' are missing, even if they simply should not get changed.

3.7. validateAttributeLogic

expected results: void or exceptions (if any part of the custom validation fails)

For more complex/logical checks the laravel HTTP parameter validation might not be sufficient, e.g. when a property depends highly on other objects' relations. Thus the BaseModelController's 'editObjectContents' method calls the models' 'validateAttributeLogic' method, which serves as a hook AFTER the object properties get updated, but BEFORE the changes get stored into the database.

All custom checks and validations regarding a model's properties (and related objects' requirements) can be placed in the 'validateAttributeLogic' and appropriate exceptions can be thrown on validation failures. All possibly thrown exceptions will be caught within the 'editObjectContents' method and be transferred into a BulkValidationException.

See section Exceptions for more details on the package's exception handling.

4. Available Features

The BaseModelTrait provides several handy methods to support your models and controller actions. Once the models are configured correctly, many basic behaviours will happen automatically or with minimum coding effort.

4.1. Model Default values

The BaseModelTrait comes with the possibility to prefill default values on an object's instantiation. The 'getDefaults' method can be configured to return an array of all default values for a model's properties, e.g.:

4.2. Relationship configurations (Bulk Actions)

A model can use its relations for 'bulk actions'. These bulk actions allow multiple related models to be managed in a single request instead of calling one request per each model action.

If the classes Post and Comment have a One-To-Many relationship (one Post can have many Comments), and the 'comments' relation within Post is configured as editable, an Update/Create on the Post endpoint will also update/create the given Comments.

The following scenario describes this use case in detail:

1) Post model defines its relation to the Comment as editable (a change request to Post can 'go downwards' and trigger a change in one or many of its Comments):

2) Comment model defines its relation to the Post model to be uneditable (a change request on a Comment can not 'go upwards' and trigger a change in its Post).

3) If now a POST request for a new Post occurs that contains the defined relation field 'comments', all contents of 'comments' will be stored as Comment objects, e.g.:

This request will create a new Post with name 'Post 1' AND two new Comments with the texts: 'A comment from a user' and 'Another comment from a user' without the necessity to call two additional POST requests for the two comments.

4.3. Extended all and find methods

The BaseModelTrait implements the two improved model methods 'allExtended' and 'findExtended'. They are extended versions of eloquent models' 'all' and 'find' methods and behave as following:

4.3.1. Static Method allExtended

This method adds BaseModel features to the basic 'all' method of each eloquent model:

While all of those features can be configured via GET request parameters - see section HTTP List request options and parameters for further detail on the possible parameter configurations during a request - some of them can also be prefilled when calling the 'allExtended' method in a class (e.g. a REST controller). The method definition from the BaseModelInterface looks like this:

The 'columns' and 'includes' arrays will affect the model's attributes and relations that will be returned. They do not affect the SQL query itself, but will influence the representation of the resultSet (received via Illuminate\Pagination\LengthAwarePaginator).

The 'filters' and 'searches' arrays will directly affect the SQL query itself and will be accumulated like this: SELECT ... WHERE ( ( $filters AND (GET-filters from request) ) OR $orFilters ) AND ( $searches OR $orSearches )

The following section will describe how the 'allExtended' ExtendedModelParameters methods can be used directly on method call, regardless of possible HTTP request parameters.

4.3.1.1. Parameters

So as the 'add' method once can specify the following configuration when fetching a bunch of objects:

4.3.1.1.1 setColumns

Plain array that defines the columns (= model's properties), that are to be returned for all found objects. The object ids will always be returned, regardless of the settings of the 'columns' variable. Example

will only return the names (and ids) of all found post entries:

4.3.1.1.2. setFilters

Multi-Array of 'WHERE x = y' filtering conditions that get nested like this:

Example

will result in the following SQL query:

4.3.1.1.3. setOrFilters

Multi-Array of 'WHERE ... OR x = y' filtering conditions that get nested like this:

Example

will result in the following SQL query:

4.3.1.1.4. setIncludes

Plain array of all model relations (their method's names) that are to be included into the resulting list.

Example

will return the wanted relations' properties along with the found post entries:

4.3.1.1.5. setSearches

Multi-Array of 'WHERE X LIKE "y"' filtering conditions that get nested like this:

Example

will result in the following SQL query:

Respectively, since PostgreSQL only supports LIKE and ILIKE (case insensitive LIKE) queries for character/text fields, for PostgreSQL connections the query will be:

4.3.1.1.6. setOrSearches

Multi-Array of 'WHERE ... OR X LIKE "y"' filtering conditions that get nested like this:

Example

will result in the following SQL query:

Respectively, since PostgreSQL only supports LIKE and ILIKE (case insensitive LIKE) queries for character/text fields, for PostgreSQL connections the query will be:

4.3.1.1.7 setPagination (seventh parameter)

Integer or null to avoid the model's default pagination. Can not exceed the model's $maxPagination value (automatically reduced).

4.3.1.1.8 setDecryptionKey (eighth parameter)

String or null to use for the decryption of encrypted properties of a model that uses the anexia/encryption package. If the correct decryption key is given, the encrypted properties will automatically be decrypted and returned. If no decryption key is given, the encrypted properties will be excluded from the response.

4.3.2. Static method findExtended

This method adds BaseModel features to the basic 'find' method of each eloquent model:

While all of those features can be configured via GET request parameters - see section HTTP List request options and parameters for further detail on the possible parameter configurations during a request - some of them can also be prefilled when calling the 'findExtended' method in a class (e.g. a REST controller). The method definition from the BaseModelInterface looks like this:

The 'columns' and 'includes' arrays will affect the model's attributes and relations that will be returned. They do not affect the SQL query itself, but will influence the representation of the resulting object.

The 'filters' array will directly affect the SQL query itself and will be accumulated like this: SELECT ... WHERE $filters

The following section will describe how the 'findExtended' ExtendedModelParameters methods can be used directly on method call, regardless of possible HTTP request parameters.

4.3.2.1. Parameters

So as the 'add' method once can specify the following configuration when fetching a bunch of objects:

4.3.2.1.1. setColumns (second parameter)

Plain array that defines the columns (= model's properties), that are to be returned for the found object. The object id will always be returned, regardless of the settings of the 'columns' variable. Example

will only return the name (and id) of the found post entry:

4.3.2.1.2. setFilters (third parameter)

Multi-Array of 'WHERE x = y' filtering conditions that get nested like this:

Example

will result in the following SQL query:

4.3.2.1.3 setIncludes (fourth parameter)
4.3.2.1.4 setPagination (fifth parameter)

Integer or null to avoid the model's default pagination. Can not exceed the model's $maxPagination value (automatically reduced).

4.3.2.1.5 setDecryptionKey (sixth parameter)

String or null to use for the decryption of encrypted properties of a model that uses the anexia/encryption package. If the correct decryption key is given, the encrypted properties will automatically be decrypted and returned. If no decryption key is given, the encrypted properties will be excluded from the response.

4.4. Exceptions

The BaseModel package comes with two built-in exception classes:

4.4.1. SqlException

When the BaseModelController's 'editObjectContents' method catches a standard QueryException (Illuminate\Database), it looks for certain PostgreSQL error codes and translates them into SqlExceptions with default status code 400 and the corresponding info text as 'message'.

4.4.2. BulkValidationException

When the BaseModelController's 'editObjectContents' method catches any exception's whatsoever, it puts their message (or messages, if multiple exceptions get thrown in the course of the edition of multiple related objects) into a BulkValidationException's 'messages' field. The BulkValidationException defaults to a status code 400 and has both a 'message' field (which by default says 'Error in bulk validation') and a 'messages' field (accessible during the 'getMessages' method) that contains the collected exception's messages with further details to the actual occurring errors.

4.5. HTTP List request options and parameters

4.5.1. Sorting

Each endpoint request that provides lists of multiple entities can be sorted according to the related entities' properties.

The BaseModel comes with a default sorting for list requests (GET with no specific id, e.g.: GET /posts). With the getDefaultSorting method in a BaseModel the fields and direction to sort by can be defined.

The above example will always return post lists sorted by their names in ascending order. If multiple fields are defined for the default sorting they will be processed from top to bottom (top first, bottom last).

Example The following definition

results in the post lists to be sorted by names in ascending order and types in descending order.

4.5.1.1. Custom sorting

The default sort_field and sort_direction can be modified via GET parameters:

The 'sort_field' parameter can be any property that comes with the result of the requested entity. The 'sort_direction' for each 'sort_field' is 'ASC' by default. To change it, the parameter must always include the correlating property as key:

Multiple 'sort_field' and 'sort_direction' parameters can be combined to create a multiply sorted result. The given order of the 'sort_field' parameters will define the sorting order within the internal SQL query, e.g.:

will result in internal SQL query

If 'sort_direction' parameters are given without corresponding 'sort_field' parameter, they will be added (in the given order) after the 'sort_field' parameter conditions, e.g.:

will result in internal SQL query

Even though the 'sort_direction[name]' parameter was before sort_field[]=type it will be added afterwards, so as conclusion the order of the sorting-results is:

4.5.2. Filtering

Each endpoint request that provides lists of multiple entities can be filtered to return only those results that show the required values for the given attributes.

Example

GET /posts?author_id=1 will only return the posts of the author with id 1

4.5.2.1. AND Filtering (multiple filters)

Filters usually get added via AND constraint, so multiple filters can be combined in one request.

Example

GET /posts?author.name=Someone&type=SomeType will only return the posts that have the type = 'SomeType' AND belong to the author with name = 'Someone'

4.5.2.2. OR Filtering (multiple valid values for the same filter)

To allow several possible values for one filter, the OR constraint can be used by making the filter an array.

Example

GET /posts?name[]=test post&name[]=Another post will only return the posts that have the name = 'test post' or name = 'Another post'.

4.5.2.3 Prepared filters

Some of the models come with prepared filter statements to support certain queries. The existing prepared filters are listed in each endpoint section. To call them, simply use the "prepared_filter" GET parameter

Example Assuming, the post model has a filter "current_comments" defined:

GET /posts?prepared_filter[]=current_comments will only return the posts with type "comment" and property year=2017.

Prepared filters can be combined just like any other filter:

Example GET /posts?prepared_filter[]=current_comments&name=post_name will only return the posts with property year=2017 and name "post_name".

Note The prepared filter "current_comments" gives the same output as a query for year=2017&type=comment would. Prepared filters only makes sense for queries with more filter values than one.

Prepared complex filters

Other than "simple" prepared filters, which merely represent a combination of straight forward AND / OR filters, a model can contain more complex filter structure, including joins or sub-queries.

Example Assuming, the post model has a filter "name_shorter_10" defined:

GET /api/v1/bricks?prepared_filter[]=name_shorter_10 will only return all posts with a name shorter than 10 characters.

Prepared complex filters can be combined just like any other filter:

Example GET /api/v1/bricks?prepared_filter[]=name_shorter_10&year=2017 only return all posts with a name shorter than 10 characters and the property year=2017.

4.5.3. Searching

To trigger a case insensitive 'LIKE' sql search (case insensitive LIKE), the 'search' GET parameter can be used. By default the model properties defined in the 'getDefaultSearch' method will be searched if no explicit property name is given with the search parameter.

Example

GET /posts?search=test will return all posts with name LIKE '%test%' OR type LIKE '%test%'.

GET /posts?search[type]=test will return all posts with type LIKE '%test%'.

4.5.3.1. Search at field start or end

To look for a substring at the beginning of a field, the 'search_start' GET parameter can be used. It can also be used on the default search properties or on specific properties:

Example

GET /posts?search_start=test will return all posts with name LIKE 'test%' OR type LIKE 'test%'.

GET /posts?search_start[type]=test will return all posts with type LIKE 'test%'.

The same applies for the 'search_end' GET parameter that can be used to find substrings at the beginning of a field:

Example

GET /posts?search_end=test will return all posts with name LIKE '%test' OR type LIKE '%test'.

GET /posts?search_end[type]=test will return all posts with type LIKE '%test'.

4.5.3.2. AND Searching (multiple search conditions)

Whenever multiple 'search', 'search_start', 'search_end' parameters are given in the GET request, they are AND connected in the resulting query.

Example

GET /posts?search=test&search_end[type]=foo will return all posts with ((name LIKE '%test%' OR type LIKE '%test%') AND type LIKE '%foo').

4.5.3.3. OR Searching (multiple valid values for the same search condition)

To define multiple possible values for the search on the same fields, the values can be arranged as arrays:

Example

GET /posts?search[]=test&search[]=foo will return all posts with name LIKE '%test%' OR type LIKE '%test%' OR name LIKE '%foo%' OR type LIKE '%foo%'.

Multiple AND and OR combinations of search filters can be applied in one GET request to create complex searches.

Example

GET /posts?search[]=test&search_end[type]=foo&search[]=foo&search_start[name]=bar will return all posts with ((name LIKE '%test%' OR type LIKE '%test%' OR name LIKE '%foo%' OR type LIKE '%foo%') AND type LIKE '%foo' AND name LIKE 'bar%').

4.5.4. Pagination

For GET requests on lists of models (e.g. GET /posts), the default pagination is always 10 items per page, starting with page 1 (items 0 - 10).

The paginated response always show the following structure:

To change the default pagination within the application, the BaseModel's 'setPagination' method can be used.

To change the number of items shown per page directly on request, the GET parameter 'pagination' can be used. To change the currently shown page, the GEt parameter 'page' can be used, but careful: if the given page exceeds the number of available pages for the current list (is greater than 'last_page'), there will not be an error response, but a valid response with an empty collection of items ('data').

Example

GET /posts?pagination=100&page=2 will return all posts with ((name LIKE '%test%' OR type LIKE '%test%' OR name LIKE '%foo%' OR type LIKE '%foo%') AND type LIKE '%foo' AND name LIKE 'bar%').

5. Testing

The package comes with a basic test class for BaseModels and a more general DbTestCase that uses DatabaseTransactions to keep changes to the test db temporary (changes are undone after each test method).

5.1. Model Tests (Unit Tests)

The BaseModelTestCase includes tests for all models' defined default values for properties/attributes and a check whether their relation definitions are complete (corresponding definition in related models).

To use the two provided tests for a BaseModel, the BaseModelTestCase class can be extended (abstract methods need to be implemented). Afterwards the two tests 'testInverseRelationsForBulkActions' and 'testDefaultValues' will be available for the newly created test class:

By running the phpunit tests, the tests from BaseModelTestCase will be executed for the Post model.

5.2. Controller Tests (Feature Tests)

The RestControllerTestCase provides a check method for the pagination as described in section Pagination. This check makes sure, all pagination related fields are set in the list response.

To use this method the RestControllerTestCase can be extended (abstract methods need to be implemented) and after a (mocked) GET list request, the pagination check can be included:

5.3. DbTestCase

Both, BaseModelTestCase and RestControllerTestCase use the DbTestCase, which allows DatabaseTransactions. By default, all tests use the database connection defined as 'pgsql_testing'. At the first test in each run the database gets created from scratch (using the commands 'php artisan migrate' and 'php artisan db:seed').

6. List of developers

7. Project related external resources


All versions of laravel-basemodel with dependencies

PHP Build Version
Package Version
Requires php Version >=5.6.4
anexia/laravel-encryption Version ^1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package anexia/laravel-basemodel contains the following files

Loading the files please wait ....