├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MAINTAINERS.md ├── README.md ├── composer.json └── src ├── ServiceProvider.php └── macros.php /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | - Algolia Client Version: #.#.# 15 | - Language Version: 16 | 17 | ### Description 18 | 19 | 20 | ### Steps To Reproduce 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | | Q | A 2 | | ----------------- | ---------- 3 | | Bug fix? | yes/no 4 | | New feature? | yes/no 5 | | BC breaks? | no 6 | | Related Issue | Fix #... 7 | | Need Doc update | yes/no 8 | 9 | 10 | ## Describe your change 11 | 12 | 16 | 17 | ## What problem is this fixing? 18 | 19 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v0.5.0 2 | 3 | * Support Laravel Scout v4 4 | * Fix User Agent 5 | 6 | 7 | ## v0.4.0 8 | 9 | * Ensure `hydrate` properly plays with Eloquent quarded attributes 10 | 11 | ## v0.3.0 12 | 13 | * Added `hydrate` macro to support populating models directly from Algolia responses 14 | 15 | ## v0.2.0 16 | 17 | * Renamed `around` to `aroundLatLng` 18 | * Added `with` macro to support any Algolia option 19 | 20 | ## v0.1.0 21 | 22 | Initial release 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Hi there! We're thrilled that you'd like to contribute to this project. 4 | Your help is essential to keeping it great. 5 | 6 | ### Opening an issue 7 | 8 | Each repository provides a template for issues. Please tell us the client and language version, and 9 | provide a clear description of the problem you're facing. Steps to reproduce, or example code 10 | (repository, jsfiddle, and such), are a big help. 11 | 12 | ### Submitting a pull request 13 | 14 | Keep your changes as focused as possible. If there are multiple changes you'd like to make, 15 | please consider submitting them as separate pull requests unless they are related to each other. 16 | 17 | Here are a few tips to increase the likelihood of being merged: 18 | 19 | - [ ] Write tests. 20 | - [ ] Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 21 | - [ ] Allow [edits from maintainers](https://blog.github.com/2016-09-07-improving-collaboration-with-forks/). 22 | 23 | ### Security issues 24 | If you find any security risk in the project, please open an issue. 25 | 26 | ### API Breaking changes 27 | 28 | We care deeply about backward compatibility for our API clients libraries. 29 | If it's necessary, we're ready to break backward compatibility, 30 | but this should be pretty rare. 31 | 32 | If you want to make a change that will break the backward compatibility of the API, 33 | open an issue first to discuss it with the maintainers. 34 | 35 | ### Editing `README.md` and similar files 36 | 37 | Note that some files are managed outside this repository and are committed automatically. 38 | 39 | The `README.md` is generated automatically from our doc. If you'd like us to update this file, 40 | feel free to open an issue. 41 | 42 | `.github` directory is managed in [this repository](https://github.com/algolia/algoliasearch-client-common), 43 | any Pull Request there is welcome. 44 | 45 | ## Label caption 46 | 47 | Labels across all Algolia API clients repositories are normalized. 48 | 49 | 50 | 51 | | Label | Meaning | 52 | |---------------------------------------------------------------------------|----------------------------------------------------------------------------------------| 53 | | ![#050f2c](https://placehold.it/15/050f2c/000000?text=+) Do not merge | PR should not be merged (decided by maintainers) | 54 | | ![#ffc168](https://placehold.it/15/ffc168/000000?text=+) WIP | PR is not ready, no need to look at it (decided by contributors) | 55 | | ![#2ede98](https://placehold.it/15/2ede98/000000?text=+) Ready | The PR is ready, reviewed, tests are green, if you're brave enough: click merge button | 56 | | ![#ffc168](https://placehold.it/15/ffc168/000000?text=+) Waiting for API | The feature is implemented but the REST API is not live yet | 57 | | ![#3369e6](https://placehold.it/15/3369e6/000000?text=+) Discussion | We need everyone's opinion on this, please join the conversation and share your ideas | 58 | | ![#3369e6](https://placehold.it/15/3369e6/000000?text=+) Support | A user needs help but it's not really a bug | 59 | | ![#3369e6](https://placehold.it/15/3369e6/000000?text=+) API feature | New API feature added to every client (like query rules) | 60 | | ![#3369e6](https://placehold.it/15/3369e6/000000?text=+) Chore | CI, docs, and everything around the code | 61 | | ![#ff4f81](https://placehold.it/15/ff4f81/000000?text=+) Bug | It's a bug, fix it! | 62 | | ![#b60205](https://placehold.it/15/b60205/000000?text=+) Breaking change | RED ALERT! This means we need a new major version | 63 | | ![#ff6c5f](https://placehold.it/15/ff6c5f/000000?text=+) Good First Issue | If you want to contribute, this one is _easy_ to tackle! | 64 | 65 | 66 | 67 | 68 | ## Resources 69 | 70 | - [Contributing to Open Source on GitHub](https://guides.github.com/activities/contributing-to-open-source/) 71 | - [Using Pull Requests](https://help.github.com/articles/using-pull-requests/) 72 | - [GitHub Help](https://help.github.com) 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-Present Algolia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | ## `algolia/laravel-scout-algolia-macros` maintainers 2 | 3 | | Name | Email | 4 | |-----------------|-----------------------------| 5 | | Julien Bourdeau | julien.bourdeau@algolia.com | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **DEPRECATED: Use of this repository is deprecated. Please use Scout Extended - https://github.com/algolia/scout-extended instead.** 2 | 3 | # Laravel Scout Algolia Macros 4 | 5 | A collection of useful macros to extend Laravel Scout capabilities when using the [Algolia engine](https://laravel.com/docs/5.4/scout#driver-prerequisites). 6 | 7 | This package aims to provide a set of macros to take advantage of the 8 | Algolia-specific feature. 9 | 10 | 11 | ## Installation 12 | 13 | Pull the package using composer 14 | 15 | ``` 16 | composer require algolia/laravel-scout-algolia-macros 17 | ``` 18 | 19 | Next, you should add the `Algolia\ScoutMacros\ServiceProvider` to the `providers` 20 | array of your `config/app.php` configuration file: 21 | 22 | ```php 23 | Algolia\ScoutMacros\ServiceProvider::class 24 | ``` 25 | 26 | 27 | ## Usage 28 | 29 | ### `count` 30 | 31 | The count method will return the number of results after the request to Algolia. 32 | 33 | The point is to avoid pull data from the database and building the collection. 34 | 35 | ```php 36 | $nbHits = Model::search('query')->count(); 37 | ``` 38 | 39 | ### `hydrate` 40 | 41 | The `hydrate` method is similar to the standard get() method, except it hydrates the models from your Algolia index. 42 | 43 | By default, Scout will use the IDs of the results from Algolia and pull the data from the local database to create the collection. 44 | 45 | Hence, `hydrate` will be much faster than `get`. 46 | 47 | 48 | **Note**: By using this method you must be sure that you are correctly keeping your algolia index in sync with your database 49 | to avoid populating stale data. 50 | 51 | #### Restrict attributes 52 | 53 | By default, this method will add all attributes from Algolia's record to your model. If you want to remove sensitive or irrelevant data from your model, you have two options. 54 | 55 | You can set a list of retrievable attributes in your Algolia dashboard. In this case, Algolia will only return these attributes while still searching every `searchableAttributes`. 56 | 57 | You may as well use the laravel `$guarded` attributes of your model class. For instance, if you don't want to see the `_h` attribute in your collection, you will have the following. 58 | 59 | ```php 60 | namespace App; 61 | 62 | use Illuminate\Database\Eloquent\Model; 63 | use Laravel\Scout\Searchable; 64 | 65 | class People extends Model 66 | { 67 | use Searchable; 68 | 69 | protected $guarded = ['_highlightResult']; 70 | } 71 | ``` 72 | 73 | ### `with` 74 | 75 | The `with` method gives you complete access to the Algolia options parameter. This allows you 76 | to customise the search parameters exactly the same as you would using the algolia php library directly. 77 | 78 | #### Simple example 79 | 80 | ```php 81 | $result = Model::search('') 82 | ->with(['hitsPerPage' => 30]) 83 | ->get(); 84 | ``` 85 | 86 | #### Advanced example 87 | 88 | ```php 89 | 90 | $filters = [ 91 | 'averge_ratings >= 3', 92 | 'total_reviews >= 1' 93 | ]; 94 | 95 | $filterString = implode(' AND ', $filters); 96 | 97 | $params = [ 98 | 'aroundLatLng' => $lat.','.$lon, 99 | 'hitsPerPage' => 30, 100 | 'page' => 0, 101 | 'aroundRadius' => 30000, //30km 102 | 'aroundPrecision' => 200, //200 Meters 103 | 'getRankingInfo' => true, //return ranking information in results 104 | 'filters' => $filterString // add filters 105 | ]; 106 | 107 | $result = Model::search('')->with($params)->get(); 108 | 109 | ``` 110 | 111 | 112 | ### `aroundLatLng` 113 | 114 | The`aroundLatLng` method will add [geolocation parameter](1) to the search request. You 115 | can define a point with its coordinate. 116 | 117 | Note that this method is pure syntactic sugar, you can use `with` to specify more location details (like radius for instance) 118 | 119 | ```php 120 | // Models around Paris latitude and longitude 121 | Model::search('query')->aroundLatLng(48.8588536, 2.3125377)->get(); 122 | ``` 123 | 124 | Where clauses can also be added 125 | 126 | ```php 127 | Model::search('query') 128 | ->aroundLatLng(48.8588536, 2.3125377) 129 | ->where('something_id', 1) 130 | ->get(); 131 | ``` 132 | 133 | 134 | ## Contributing 135 | 136 | Feel free to open an issue to request a macro. 137 | 138 | Open any pull request you want, so we can talk about it and improve the package. :tada: 139 | 140 | [1]: https://www.algolia.com/doc/guides/geo-search/geo-search-overview/ 141 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "algolia/laravel-scout-algolia-macros", 3 | "description": "A collection macros to extend Laravel Scout with more Algolia capabilities", 4 | "keywords": [ 5 | "algolia", 6 | "laravel-scout", 7 | "search-engine", 8 | "laravel-macros", 9 | "search" 10 | ], 11 | "type": "library", 12 | "homepage": "https://github.com/algolia/laravel-scout-algolia-macros", 13 | "license": "MIT", 14 | "authors": [ 15 | { 16 | "name": "Julien Bourdeau", 17 | "email": "support@algolia.com" 18 | } 19 | ], 20 | "minimum-stability": "stable", 21 | "require": { 22 | "laravel/scout": "3.0.5 || ~4.0 || ~5.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Algolia\\ScoutMacros\\": "src" 27 | } 28 | }, 29 | "extra": { 30 | "laravel": { 31 | "providers": [ 32 | "Algolia\\ScoutMacros\\ServiceProvider" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | engine()->search($this); 15 | 16 | return (int) $raw['nbHits']; 17 | }); 18 | } 19 | 20 | if (! Builder::hasMacro('aroundLatLng')) { 21 | /** 22 | * Search for entries around a given location. 23 | * 24 | * @see https://www.algolia.com/doc/guides/geo-search/geo-search-overview/ 25 | * 26 | * @param float $lat Latitude of the center 27 | * @param float $lng Longitude of the center 28 | * 29 | * @return Laravel\Scout\Builder 30 | */ 31 | Builder::macro('aroundLatLng', function ($lat, $lng) { 32 | $callback = $this->callback; 33 | 34 | $this->callback = function ($algolia, $query, $options) use ($lat, $lng, $callback) { 35 | $options['aroundLatLng'] = (float) $lat . ',' . (float) $lng; 36 | 37 | if ($callback) { 38 | return call_user_func( 39 | $callback, 40 | $algolia, 41 | $query, 42 | $options 43 | ); 44 | } 45 | 46 | return $algolia->search($query, $options); 47 | }; 48 | 49 | return $this; 50 | }); 51 | } 52 | 53 | if (! Builder::hasMacro('with')) { 54 | /** 55 | * Override the algolia search options to give you full control over the request, 56 | * similar to official algolia-laravel package. 57 | * 58 | * Adds the final missing piece to scout to make the library useful. 59 | * 60 | * @param array $opts Latitude of the center 61 | * 62 | * @return Laravel\Scout\Builder 63 | */ 64 | Builder::macro('with', function ($opts) { 65 | $callback = $this->callback; 66 | 67 | $this->callback = function ($algolia, $query, $options) use ($opts, $callback) { 68 | $options = array_merge($options, $opts); 69 | 70 | if ($callback) { 71 | return call_user_func( 72 | $callback, 73 | $algolia, 74 | $query, 75 | $options 76 | ); 77 | } 78 | 79 | return $algolia->search($query, $options); 80 | }; 81 | 82 | return $this; 83 | }); 84 | } 85 | 86 | if (! Builder::hasMacro('hydrate')) { 87 | /** 88 | * get() hydrates records by looking up the Ids in the corresponding database 89 | * This macro uses the data returned from the search results to hydrate 90 | * the models and return a collection 91 | * 92 | * @return Collection 93 | */ 94 | Builder::macro('hydrate', function () { 95 | $results = $this->engine()->search($this); 96 | 97 | if (count($results['hits']) === 0) { 98 | return Collection::make(); 99 | } 100 | 101 | $hits = collect($results['hits']); 102 | $className = get_class($this->model); 103 | $models = new Collection(); 104 | 105 | /* If the model is fully guarded, we unguard it. 106 | Fully garded is the default configuration and it will 107 | only result in error. 108 | If the `$guarded` attribute is set to a list of attribute 109 | we take it into account. */ 110 | if (in_array('*', $this->model->getGuarded())) { 111 | Eloquent::unguard(); 112 | } 113 | 114 | $hits->each(function($item, $key) use ($className, $models) { 115 | $models->push(new $className($item)); 116 | }); 117 | 118 | Eloquent::reguard(); 119 | 120 | return $models; 121 | }); 122 | } 123 | --------------------------------------------------------------------------------