Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
  Assets
  Commands
  Composers
  Config
  Contracts
  Database
  Entities
  Exceptions
  Facades
  Foundation
  Http
  Listeners
  Presenters
  Providers
  Repositories
  Resources
  Services
  Sidebar
  Support
  Traits
  Utils
  Validators
  .codeclimate.yml
  .csslintrc
  .eslintignore
  .eslintrc
  composers.php
  helpers.php
  module.json
  phpmd.xml
  readme.md
  start.php
  composer.json
Size: Mime:
  readme.md

Webbing CMS - Core Module

Instalação

Este modulo possui as funcionalidades basicas do sistema e as dependencias para o funcionamento do CMS e dos demais componentes.

Inclua as seguintes linhas no composer.json para instalar o módulo


    "repositories": [{
      "type": "composer",
      "url":  "https://php.fury.io/xka1LLxBsys-bkR4n8D2/webbingbrasil/"
    }],

    "require": {
        "webbingbrasil/core-module": "0.1.*",
    }

Agora execute o seguinte comando para instalar as dependencias

    composer update

Você vai encontrar o módulo no diretorio Modules/Core.

Additional Composer Packages

Additional packages to extra functionality

"thunderer/shortcode": "~0.6",
"propaganistas/laravel-phone": "~2.0",
"hashids/hashids": "1.0.5",
"ramsey/uuid": "~2.8",
"hanneskod/classtools": "~1.0",
"kalnoy/nestedset": "~4.1",
"pragmarx/zipcode": "dev-master",
"artesaos/seotools": "0.9.*",
"cboden/ratchet": "^0.3.5",

Using the RequestCriteria

RequestCriteria is a standard Criteria implementation. It enables filters to perform in the repository from parameters sent in the request.

You can perform a dynamic search, filter the data and customize the queries.

To use the Criteria in your repository, you can add a new criteria in the boot method of your repository, or directly use in your controller, in order to filter out only a few requests.

####Enabling in your Repository

use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Criteria\RequestCriteria;


class PostRepository extends BaseRepository {

	/**
     * @var array
     */
    protected $fieldSearchable = [
        'name',
        'email'
    ];

    public function boot(){
        $this->pushCriteria(app('Prettus\Repository\Criteria\RequestCriteria'));
        ...
    }

    function model(){
       return "App\\Post";
    }
}

Remember, you need to define which fields from the model can be searchable.

In your repository set $fieldSearchable with the name of the fields to be searchable.

protected $fieldSearchable = [
	'name',
	'email'
];

You can set the type of condition which will be used to perform the query, the default condition is "="

protected $fieldSearchable = [
	'name'=>'like',
	'email', // Default Condition "="
	'your_field'=>'condition'
];

####Enabling in your Controller

	public function index()
    {
        $this->repository->pushCriteria(app('Prettus\Repository\Criteria\RequestCriteria'));
        $posts = $this->repository->all();
		...
    }

Example the Criteria

Request all data without filter by request

http://prettus.local/users

[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@gmail.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    },
    {
        "id": 2,
        "name": "Lorem Ipsum",
        "email": "lorem@ipsum.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    },
    {
        "id": 3,
        "name": "Laravel",
        "email": "laravel@gmail.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    }
]

Conducting research in the repository

http://prettus.local/users?search=John%20Doe

or

http://prettus.local/users?search=John&searchFields=name:like

or

http://prettus.local/users?search=john@gmail.com&searchFields=email:=

or

http://prettus.local/users?search=name:John Doe;email:john@gmail.com

or

http://prettus.local/users?search=name:John;email:john@gmail.com&searchFields=name:like;email:=

[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@gmail.com",
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00"
    }
]

Filtering fields

http://prettus.local/users?filter=id;name

[
    {
        "id": 1,
        "name": "John Doe"
    },
    {
        "id": 2,
        "name": "Lorem Ipsum"
    },
    {
        "id": 3,
        "name": "Laravel"
    }
]

Sorting the results

http://prettus.local/users?filter=id;name&orderBy=id&sortedBy=desc

[
    {
        "id": 3,
        "name": "Laravel"
    },
    {
        "id": 2,
        "name": "Lorem Ipsum"
    },
    {
        "id": 1,
        "name": "John Doe"
    }
]

Add relationship

http://prettus.local/users?with=groups

####Overwrite params name

You can change the name of the parameters in the configuration file config/repository.php

Database Trait Behaviours

The core module comes with a system for setting up behaviours, based on Eloquence package, which are really just small libraries that you can use with your Eloquent models. The first of these is the count cache.

Count cache

Count caching is where you cache the result of a count of a related table's records. A simple example of this is where you have a user who has many posts. In this example, you may want to count the number of posts a user has regularly - and perhaps even order by this. In SQL, ordering by a counted field is slow and unable to be indexed. You can get around this by caching the count of the posts the user has created on the user's record.

To get this working, you need to do two steps:

  1. Use the Countable trait on the model and
  2. Configure the count cache settings

Configure the count cache

To setup the count cache configuration, we need to have the model use Countable trait, like so:

class Post extends Eloquent {
    use Countable;
    
    public function countCaches() {
        return [User::class];
    }
}

This tells the count cache that the Post model has a count cache on the User model. So, whenever a post is added, or modified or deleted, the count cache behaviour will update the appropriate user's count cache for their posts. In this case, it would update post_count on the user model.

The example above uses the following standard conventions:

  • post_count is a defined field on the User model table
  • user_id is the field representing the foreign key on the post model
  • id is the primary key on the user model table

These are, however, configurable:

class Post extends Eloquent {
    use Countable;
    
    public function countCaches() {
        return [
            'num_posts' => ['User', 'users_id', 'id']
        ];
    }
}

This example customises the count cache field, and the related foreign key, with num_posts and users_id, respectively.

Alternatively, you can be very explicit about the configuration (useful if you are using count caching on several tables and use the same column name on each of them):

class Post extends {
    use Countable;
    
    public function countCaches() {
        return [
            [
                'model'      => 'User',
                'field'      => 'num_posts',
                'foreignKey' => 'users_id',
                'key'        => 'id'
            ]
        ];
    }
}

If using the explicit configuration, at a minimum you will need to define the "model" parameter. The "countField", "foreignKey", and "key" parameters will be calculated using the standard conventions mentioned above if they are omitted.

With this configuration now setup - you're ready to go!

Sum cache

Sum caching is similar to count caching, except that instead of caching a count of a related table's records, you cache a sum of a particular field on the related table's records. A simple example of this is where you have an order that has many items. Using sum caching, you can cache the sum of all the items' prices, and store that sum in the order table.

To get this working -- just like count caching -- you need to do two steps:

  1. Utilise the Summable trait on the model and
  2. Configure the model for any sum caches

Configure the sum cache

To setup the sum cache configuration, simply do the following:

class Item extends Eloquent {
    use Summable;
    
    public function sumCaches() {
        return [Order::class];
    }
}

This tells the sum cache manager that the Item model has a sum cache on the Order model. So, whenever an item is added, modified, or deleted, the sum cache behaviour will update the appropriate order's sum cache for their items. In this case, it would update item_total on the Order model.

The example above uses the following conventions:

  • item_total is a defined field on the Order model table
  • total is a defined field on the Item model table (the column we are summing)
  • order_id is the field representing the foreign key on the item model
  • id is the primary key on the order model table

These are, however, configurable:

class Item extends Eloquent {
    use Summable;
    
    public function sumCaches() {
        return [
            'item_total' => ['Order', 'total', 'order_id', 'id']
        ];
    }
}

Or using the verbose syntax:

class Item extends Eloquent {
    use Summable;
    
    public function sumCaches() {
        return [
            [
                'model'       => 'Order',
                'columnToSum' => 'total',
                'field'       => 'item_total'
                'foreignKey'  => 'order_id',
                'key'         => 'id'
            ]
        ];
    }
}

Both of these examples implements the default settings.

With these settings configured, you will now see the related model's sum cache updated every time an item is added, updated, or removed.

Sluggable models

Sluggable is another behaviour that allows for the easy addition of model slugs. To use, implement the Sluggable trait:

class User extends Eloquent {
    use Sluggable;

    public function slugStrategy() {
        return 'username';
    }
}

In the example above, a slug will be created based on the username field of the User model. There are two other slugs that are supported however, as well:

  • id and
  • uuid

The only difference between the two above, is that if you're using UUIDs, the slug will be generated previous to the save, based on the uuid field. With ids, which are generally auto-increase strategies - the slug has to be generated after the record has been saved - which results in a secondary save call to the database.

Searchable Trait

Searchable allows you to perform searches in a table giving priorities to each field for the table and it's relations.

This is not optimized for big searches, but sometimes you just need to make it simple (Although it is not slow).

Usage

Add the trait to your model and your search rules.

use Modules\Core\Database\Behaviours\Searchable;

class User extends \Eloquent
{
    use Searchable;

    /**
     * Searchable rules.
     *
     * @var array
     */
    protected $searchable = [
        'columns' => [
            'users.first_name' => 10,
            'users.last_name' => 10,
            'users.bio' => 2,
            'users.email' => 5,
            'posts.title' => 2,
            'posts.body' => 1,
        ],
        'joins' => [
            'posts' => ['users.id','posts.user_id'],
        ],
    ];

    public function posts()
    {
        return $this->hasMany('Post');
    }

}

Now you can search your model.

// Simple search
$users = User::search($query)->get();

// Search and get relations
// It will not get the relations if you don't do this
$users = User::search($query)
            ->with('posts')
            ->get();

Search Paginated

As easy as laravel default queries

// Search with relations and paginate
$users = User::search($query)
            ->with('posts')
            ->paginate(20);

Mix queries

Search method is compatible with any eloquent method. You can do things like this:

// Search only active users
$users = User::where('status', 'active')
            ->search($query)
            ->paginate(20);

Custom Threshold

The default threshold for accepted relevance is the sum of all attribute relevance divided by 4. To change this value you can pass in a second parameter to search() like so:

// Search with lower relevance threshold
$users = User::where('status', 'active')
            ->search($query, 0)
            ->paginate(20);

The above, will return all users in order of relevance.

Entire Text search

By default, multi-word search terms are split and Searchable searches for each word individually. Relevance plays a role in prioritizing matches that matched on multiple words. If you want to prioritize matches that include the multi-word search (thus, without splitting into words) you can enable full text search by setting the third value to true. Example:

// Prioritize matches containing "John Doe" above matches containing only "John" or "Doe".
$users = User::search("John Doe", null, true)->get();

If you explicitly want to search for full text matches only, you can disable multi-word splitting by setting the fourth parameter to true.

// Do not include matches that only matched "John" OR "Doe".
$users = User::search("John Doe", null, true, true)->get();

How does it work?

Searchable builds a query that search through your model using Laravel's Eloquent. Here is an example query

#####Eloquent Model:

use Modules\Core\Database\Behaviours\Searchable;

class User extends \Eloquent
{
    use Searchable;

    /**
     * Searchable rules.
     *
     * @var array
     */
    protected $searchable = [
        'columns' => [
            'first_name' => 10,
            'last_name' => 10,
            'bio' => 2,
            'email' => 5,
        ],
    ];

}

#####Search:

$search = User::search('Sed neque labore', null, true)->get();

#####Result:

select `users`.*, 

-- If third parameter is set as true, it will check if the column starts with the search
-- if then it adds relevance * 30
-- this ensures that relevant results will be at top
(case when first_name LIKE 'Sed neque labore%' then 300 else 0 end) + 

-- For each column you specify makes 3 "ifs" containing 
-- each word of the search input and adds relevace to 
-- the row

-- The first checks if the column is equal to the word,
-- if then it adds relevance * 15
(case when first_name LIKE 'Sed' || first_name LIKE 'neque' || first_name LIKE 'labore' then 150 else 0 end) + 

-- The second checks if the column starts with the word,
-- if then it adds relevance * 5
(case when first_name LIKE 'Sed%' || first_name LIKE 'neque%' || first_name LIKE 'labore%' then 50 else 0 end) + 

-- The third checks if the column contains the word, 
-- if then it adds relevance * 1
(case when first_name LIKE '%Sed%' || first_name LIKE '%neque%' || first_name LIKE '%labore%' then 10 else 0 end) + 

-- Repeats with each column
(case when last_name LIKE 'Sed' || last_name LIKE 'neque' || last_name LIKE 'labore' then 150 else 0 end) + 
(case when last_name LIKE 'Sed%' || last_name LIKE 'neque%' || last_name LIKE 'labore%' then 50 else 0 end) +
(case when last_name LIKE '%Sed%' || last_name LIKE '%neque%' || last_name LIKE '%labore%' then 10 else 0 end) + 

(case when bio LIKE 'Sed' || bio LIKE 'neque' || bio LIKE 'labore' then 30 else 0 end) + 
(case when bio LIKE 'Sed%' || bio LIKE 'neque%' || bio LIKE 'labore%' then 10 else 0 end) + 
(case when bio LIKE '%Sed%' || bio LIKE '%neque%' || bio LIKE '%labore%' then 2 else 0 end) + 

(case when email LIKE 'Sed' || email LIKE 'neque' || email LIKE 'labore' then 75 else 0 end) + 
(case when email LIKE 'Sed%' || email LIKE 'neque%' || email LIKE 'labore%' then 25 else 0 end) + 
(case when email LIKE '%Sed%' || email LIKE '%neque%' || email LIKE '%labore%' then 5 else 0 end) 

as relevance 
from `users` 
group by `id` 

-- Selects only the rows that have more than
-- the sum of all attributes relevances and divided by 4
-- Ej: (20 + 5 + 2) / 4 = 6.75
having relevance > 6.75 

-- Orders the results by relevance
order by `relevance` desc