├── .editorconfig
├── .idea
├── encodings.xml
├── modules.xml
├── php.xml
├── starter-framework.iml
└── vcs.xml
├── .styleci.yml
├── CHANGELOG.md
├── CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── composer.json
└── src
└── Someline
├── Api
├── Auth
│ └── Provider
│ │ ├── OAuth2.php
│ │ └── Passport.php
├── Foundation
│ └── Validation
│ │ └── ValidatesRequests.php
└── Middleware
│ ├── ApiAccessMiddleware.php
│ ├── ApiAuthMiddleware.php
│ └── AutoRenewJwtToken.php
├── Auth
└── AuthUserHelpers.php
├── Base
├── Api
│ └── Controllers
│ │ └── Controller.php
├── Events
│ └── Event.php
├── Http
│ └── Controllers
│ │ └── Controller.php
├── Models
│ └── BaseModel.php
├── Policies
│ └── Policy.php
├── Presenters
│ └── Presenter.php
├── Repositories
│ ├── Eloquent
│ │ └── Repository.php
│ └── Interfaces
│ │ └── RepositoryInterface.php
└── Transformers
│ └── Transformer.php
├── Foundation
└── helpers.php
├── Model
├── Basic
│ ├── CountryModel.php
│ └── PhoneNumberModel.php
├── Foundation
│ └── User.php
├── Interfaces
│ └── BaseModelEventsInterface.php
├── Observers
│ └── BaseModelObserver.php
└── Traits
│ └── BaseModelEvents.php
├── Presenters
└── BasicPresenter.php
├── Repositories
├── Criteria
│ ├── AuthUserCriteria.php
│ ├── OwnerUsersCriteria.php
│ └── RequestCriteria.php
└── PresenterRepository.php
├── Repository
├── Generators
│ ├── BindingsGenerator.php
│ ├── Commands
│ │ ├── BindingsCommand.php
│ │ ├── CommandBase.php
│ │ ├── ControllerCommand.php
│ │ ├── CriteriaCommand.php
│ │ ├── EntityCommand.php
│ │ ├── PresenterCommand.php
│ │ ├── RepositoryCommand.php
│ │ ├── TransformerCommand.php
│ │ └── ValidatorCommand.php
│ ├── ControllerGenerator.php
│ ├── CriteriaGenerator.php
│ ├── FileAlreadyExistsException.php
│ ├── Generator.php
│ ├── MigrationGenerator.php
│ ├── Migrations
│ │ ├── NameParser.php
│ │ ├── RulesParser.php
│ │ └── SchemaParser.php
│ ├── ModelGenerator.php
│ ├── PresenterGenerator.php
│ ├── RepositoryEloquentGenerator.php
│ ├── RepositoryInterfaceGenerator.php
│ ├── Stub.php
│ ├── Stubs
│ │ ├── bindings
│ │ │ └── bindings.stub
│ │ ├── controller
│ │ │ └── controller.stub
│ │ ├── criteria
│ │ │ └── criteria.stub
│ │ ├── migration
│ │ │ ├── change.stub
│ │ │ └── create.stub
│ │ ├── model.stub
│ │ ├── presenter
│ │ │ └── presenter.stub
│ │ ├── repository
│ │ │ ├── eloquent.stub
│ │ │ └── interface.stub
│ │ ├── seed.stub
│ │ ├── transformer
│ │ │ └── transformer.stub
│ │ └── validator
│ │ │ └── validator.stub
│ ├── TransformerGenerator.php
│ └── ValidatorGenerator.php
└── Providers
│ └── RepositoryServiceProvider.php
├── Support
├── Controllers
│ └── LocaleController.php
└── Middleware
│ └── LocaleMiddleware.php
└── Transformers
└── BasicTransformer.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs.
2 | ; More information at http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | indent_size = 4
9 | indent_style = space
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
14 | [*.md]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/php.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/starter-framework.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: psr2
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All Notable changes to `starter-framework` will be documented in this file.
4 |
5 | Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
6 |
7 | ## NEXT - YYYY-MM-DD
8 |
9 | ### Added
10 | - Nothing
11 |
12 | ### Deprecated
13 | - Nothing
14 |
15 | ### Fixed
16 | - Nothing
17 |
18 | ### Removed
19 | - Nothing
20 |
21 | ### Security
22 | - Nothing
23 |
--------------------------------------------------------------------------------
/CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4 |
5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
6 |
7 | Examples of unacceptable behavior by participants include:
8 |
9 | * The use of sexualized language or imagery
10 | * Personal attacks
11 | * Trolling or insulting/derogatory comments
12 | * Public or private harassment
13 | * Publishing other's private information, such as physical or electronic addresses, without explicit permission
14 | * Other unethical or unprofessional conduct.
15 |
16 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
17 |
18 | This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community in a direct capacity. Personal views, beliefs and values of individuals do not necessarily reflect those of the organisation or affiliated individuals and organisations.
19 |
20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
21 |
22 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
23 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and will be fully **credited**.
4 |
5 | We accept contributions via Pull Requests on [Github](https://github.com/someline/starter-framework).
6 |
7 |
8 | ## Pull Requests
9 |
10 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
11 |
12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests.
13 |
14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
15 |
16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
17 |
18 | - **Create feature branches** - Don't ask us to pull from your master branch.
19 |
20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
21 |
22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
23 |
24 |
25 | ## Running Tests
26 |
27 | ``` bash
28 | $ composer test
29 | ```
30 |
31 |
32 | **Happy coding**!
33 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Libern Lin
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
13 | > all 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
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Someline Starter Framework (Kernel)
2 |
3 | [![Latest Version on Packagist][ico-version]][link-packagist]
4 | [![Software License][ico-license]](LICENSE.md)
5 | [![Total Downloads][ico-downloads]][link-downloads]
6 |
7 | The [Someline Starter](https://starter.someline.com/) Framework.
8 |
9 | ## Change log
10 |
11 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
12 |
13 | ## Contributing
14 |
15 | Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.
16 |
17 | ## Security
18 |
19 | If you discover any security related issues, please email libernlin@gmail.com instead of using the issue tracker.
20 |
21 | ## Credits
22 |
23 | - [Libern Lin][link-author]
24 | - [All Contributors][link-contributors]
25 |
26 | ## License
27 |
28 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
29 |
30 | [ico-version]: https://img.shields.io/packagist/v/someline/starter-framework.svg?style=flat-square
31 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
32 | [ico-travis]: https://img.shields.io/travis/someline/starter-framework/master.svg?style=flat-square
33 | [ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/someline/starter-framework.svg?style=flat-square
34 | [ico-code-quality]: https://img.shields.io/scrutinizer/g/someline/starter-framework.svg?style=flat-square
35 | [ico-downloads]: https://img.shields.io/packagist/dt/someline/starter-framework.svg?style=flat-square
36 |
37 | [link-packagist]: https://packagist.org/packages/someline/starter-framework
38 | [link-travis]: https://travis-ci.org/someline/starter-framework
39 | [link-scrutinizer]: https://scrutinizer-ci.com/g/someline/starter-framework/code-structure
40 | [link-code-quality]: https://scrutinizer-ci.com/g/someline/starter-framework
41 | [link-downloads]: https://packagist.org/packages/someline/starter-framework
42 | [link-author]: https://github.com/libern
43 | [link-contributors]: ../../contributors
44 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "someline/starter-framework",
3 | "type": "framework",
4 | "description": "The Someline Starter Framework.",
5 | "keywords": [
6 | "someline",
7 | "starter-framework"
8 | ],
9 | "homepage": "https://github.com/someline/starter-framework",
10 | "license": "MIT",
11 | "authors": [
12 | {
13 | "name": "Libern Lin",
14 | "email": "libernlin@gmail.com",
15 | "homepage": "https://www.someline.com/",
16 | "role": "Developer"
17 | }
18 | ],
19 | "require": {
20 | "php": "^7.1.3",
21 | "ext-pdo_sqlite": "*",
22 | "fideloper/proxy": "^4.0",
23 | "laravel/framework": "5.8.*|6.0.*",
24 | "laravel/tinker": "^1.0",
25 | "predis/predis": "~1.1",
26 | "doctrine/dbal": "~2.9",
27 | "itsgoingd/clockwork": "^4.0",
28 | "guzzlehttp/guzzle": "~6.3",
29 | "lukasoppermann/http-status": "^2.0",
30 | "prettus/l5-repository": "^2.6",
31 | "prettus/laravel-validation": "1.1.*",
32 | "intervention/image": "^2.4",
33 | "intervention/imagecache": "^2.3",
34 | "barryvdh/laravel-ide-helper": "^2.6",
35 | "someline/rest-api-client": "1.2.*",
36 | "someline/someline-image": "2.3.*",
37 | "mcamara/laravel-localization": "1.3.*",
38 | "laravel/passport": "^7.2",
39 | "monarobase/country-list": "^2.1",
40 | "libern/timezone": "^1.0",
41 | "giggsey/libphonenumber-for-php": "~8.10",
42 | "torann/geoip": "1.0.*"
43 | },
44 | "require-dev": {
45 | "phpunit/phpunit": "~4.0||~5.0||~6.0||~7.0",
46 | "scrutinizer/ocular": "~1.1",
47 | "squizlabs/php_codesniffer": "~2.3"
48 | },
49 | "autoload": {
50 | "files": [
51 | "src/Someline/Foundation/helpers.php"
52 | ],
53 | "psr-4": {
54 | "Someline\\": "src/Someline"
55 | }
56 | },
57 | "autoload-dev": {
58 | "psr-4": {
59 | "Someline\\Test\\": "tests"
60 | }
61 | },
62 | "scripts": {
63 | "test": "phpunit",
64 | "format": "phpcbf --standard=psr2 src/"
65 | },
66 | "extra": {
67 | "branch-alias": {
68 | "dev-master": "1.0-dev"
69 | },
70 | "laravel": {
71 | "providers": [
72 | "Someline\\Repository\\Providers\\RepositoryServiceProvider"
73 | ]
74 | }
75 | },
76 | "minimum-stability": "dev"
77 | }
78 |
--------------------------------------------------------------------------------
/src/Someline/Api/Auth/Provider/OAuth2.php:
--------------------------------------------------------------------------------
1 | resource;
19 | }
20 |
21 | /**
22 | * @return \League\OAuth2\Server\Entity\AccessTokenEntity
23 | */
24 | public function getAccessToken()
25 | {
26 | return $this->resource->getAccessToken();
27 | }
28 |
29 |
30 | /**
31 | * @return \League\OAuth2\Server\Entity\SessionEntity
32 | */
33 | public function getSession()
34 | {
35 | return $this->getAccessToken()->getSession();
36 | }
37 |
38 | /**
39 | * Get the resource owner ID of the current request.
40 | *
41 | * @return string
42 | */
43 | public function getResourceOwnerId()
44 | {
45 | return $this->getSession()->getOwnerId();
46 | }
47 |
48 | /**
49 | * Get the resource owner type of the current request (client or user).
50 | *
51 | * @return string
52 | */
53 | public function getResourceOwnerType()
54 | {
55 | return $this->getSession()->getOwnerType();
56 | }
57 |
58 | /**
59 | * Get the client of the current request.
60 | *
61 | * @return \League\OAuth2\Server\Entity\ClientEntity
62 | */
63 | public function getClient()
64 | {
65 | return $this->getSession()->getClient();
66 | }
67 |
68 | /**
69 | * Get the client id of the current request.
70 | *
71 | * @return string
72 | */
73 | public function getClientId()
74 | {
75 | return $this->getClient()->getId();
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/src/Someline/Api/Auth/Provider/Passport.php:
--------------------------------------------------------------------------------
1 | auth = $auth->guard($this->guard);
40 | }
41 |
42 | /**
43 | * Authenticate request with a Illuminate Guard.
44 | *
45 | * @param \Illuminate\Http\Request $request
46 | * @param \Dingo\Api\Routing\Route $route
47 | *
48 | * @return mixed
49 | */
50 | public function authenticate(Request $request, Route $route)
51 | {
52 | if ( ! $user = $this->auth->user()) {
53 | throw new UnauthorizedHttpException(null, 'Unauthenticated.');
54 | }
55 |
56 | return $user;
57 | }
58 |
59 | /**
60 | * Get the providers authorization method.
61 | *
62 | * @return string
63 | */
64 | public function getAuthorizationMethod()
65 | {
66 | return 'Bearer';
67 | }
68 | }
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/Someline/Api/Foundation/Validation/ValidatesRequests.php:
--------------------------------------------------------------------------------
1 | getValidationFactory()->make($request->all(), $validator);
34 | }
35 |
36 | if ($validator->fails()) {
37 | $this->throwValidationException($request, $validator);
38 | }
39 | }
40 |
41 | /**
42 | * Validate the given request with the given rules.
43 | *
44 | * @param \Illuminate\Http\Request $request
45 | * @param array $rules
46 | * @param array $messages
47 | * @param array $customAttributes
48 | * @return void
49 | */
50 | public function validate(Request $request, array $rules, array $messages = [], array $customAttributes = [])
51 | {
52 | $validator = $this->getValidationFactory()->make($request->all(), $rules, $messages, $customAttributes);
53 |
54 | if ($validator->fails()) {
55 | $this->throwValidationException($request, $validator);
56 | }
57 | }
58 |
59 | /**
60 | * Validate the given request with the given rules.
61 | *
62 | * @param \Illuminate\Http\Request $request
63 | * @param array $data
64 | * @param array $rules
65 | * @param array $messages
66 | * @param array $customAttributes
67 | */
68 | public function validateData(Request $request, array $data, array $rules, array $messages = [], array $customAttributes = [])
69 | {
70 | $validator = $this->getValidationFactory()->make($data, $rules, $messages, $customAttributes);
71 |
72 | if ($validator->fails()) {
73 | $this->throwValidationException($request, $validator);
74 | }
75 | }
76 |
77 | /**
78 | * Validate the given request with the given rules.
79 | *
80 | * @param string $errorBag
81 | * @param \Illuminate\Http\Request $request
82 | * @param array $rules
83 | * @param array $messages
84 | * @param array $customAttributes
85 | * @return void
86 | *
87 | * @throws \Illuminate\Foundation\Validation\ValidationException
88 | */
89 | public function validateWithBag($errorBag, Request $request, array $rules, array $messages = [], array $customAttributes = [])
90 | {
91 | $this->withErrorBag($errorBag, function () use ($request, $rules, $messages, $customAttributes) {
92 | $this->validate($request, $rules, $messages, $customAttributes);
93 | });
94 | }
95 |
96 | /**
97 | * Throw the failed validation exception.
98 | *
99 | * @param \Illuminate\Http\Request $request
100 | * @param \Illuminate\Contracts\Validation\Validator $validator
101 | * @return void
102 | *
103 | * @throws \Illuminate\Foundation\Validation\ValidationException
104 | */
105 | protected function throwValidationException(Request $request, $validator)
106 | {
107 | throw new ResourceException($validator->errors()->first(), $validator->errors());
108 | // throw new ValidationException($validator, $this->buildFailedValidationResponse(
109 | // $request, $this->formatValidationErrors($validator)
110 | // ));
111 | }
112 |
113 | /**
114 | * Create the response for when a request fails validation.
115 | *
116 | * @param \Illuminate\Http\Request $request
117 | * @param array $errors
118 | * @return \Illuminate\Http\Response
119 | */
120 | protected function buildFailedValidationResponse(Request $request, array $errors)
121 | {
122 | if (($request->ajax() && !$request->pjax()) || $request->wantsJson()) {
123 | return new JsonResponse($errors, 422);
124 | }
125 |
126 | return redirect()->to($this->getRedirectUrl())
127 | ->withInput($request->input())
128 | ->withErrors($errors, $this->errorBag());
129 | }
130 |
131 | /**
132 | * Format the validation errors to be returned.
133 | *
134 | * @param \Illuminate\Contracts\Validation\Validator $validator
135 | * @return array
136 | */
137 | protected function formatValidationErrors(Validator $validator)
138 | {
139 | return $validator->errors()->getMessages();
140 | }
141 |
142 | /**
143 | * Get the URL we should redirect to.
144 | *
145 | * @return string
146 | */
147 | protected function getRedirectUrl()
148 | {
149 | return app(UrlGenerator::class)->previous();
150 | }
151 |
152 | /**
153 | * Get a validation factory instance.
154 | *
155 | * @return \Illuminate\Contracts\Validation\Factory
156 | */
157 | protected function getValidationFactory()
158 | {
159 | return app(Factory::class);
160 | }
161 |
162 | /**
163 | * Execute a Closure within with a given error bag set as the default bag.
164 | *
165 | * @param string $errorBag
166 | * @param callable $callback
167 | * @return void
168 | */
169 | protected function withErrorBag($errorBag, callable $callback)
170 | {
171 | $this->validatesRequestErrorBag = $errorBag;
172 |
173 | call_user_func($callback);
174 |
175 | $this->validatesRequestErrorBag = null;
176 | }
177 |
178 | /**
179 | * Get the key to be used for the view error bag.
180 | *
181 | * @return string
182 | */
183 | protected function errorBag()
184 | {
185 | return $this->validatesRequestErrorBag ?: 'default';
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/Someline/Api/Middleware/ApiAccessMiddleware.php:
--------------------------------------------------------------------------------
1 | exception) && $response->exception) {
37 | throw $response->exception;
38 | }
39 |
40 | return $response;
41 | } catch (OAuthException $e) {
42 | $message = env('API_DEBUG') ? $e->getMessage() : null;
43 | throw new HttpException($e->httpStatusCode, $message, $e, $e->getHttpHeaders());
44 | } catch (HttpResponseException $e) {
45 | $message = env('API_DEBUG') ? $e->getMessage() : null;
46 | throw new HttpException($e->getResponse()->getStatusCode(), $message, $e);
47 | } catch (AuthenticationException $e) {
48 | throw new UnauthorizedHttpException(null, $e->getMessage(), $e);
49 | } catch (ValidatorException $e) {
50 | $messageBag = $e->getMessageBag();
51 | throw new ResourceException($messageBag->first(), $messageBag->all());
52 | } catch (ModelNotFoundException $e) {
53 | throw new NotFoundHttpException('No results found.');
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Someline/Api/Middleware/ApiAuthMiddleware.php:
--------------------------------------------------------------------------------
1 | router = $router;
43 | $this->auth = $auth;
44 | }
45 |
46 | /**
47 | * Perform authentication before a request is executed.
48 | *
49 | * @param \Illuminate\Http\Request $request
50 | * @param \Closure $next
51 | * @param $grant
52 | *
53 | * @return mixed
54 | * @throws AccessDeniedException
55 | */
56 | public function handle($request, Closure $next, $grant = null)
57 | {
58 | $route = $this->router->getCurrentRoute();
59 |
60 | /**
61 | * FOR (Internal API requests)
62 | * @note GRANT(user) will always be able to access routes that are protected by: GRANT(client)
63 | *
64 | * For OAuth grants from password (i.e. Resource Owner: user)
65 | * @Auth will only check once, because user exists in auth afterwards
66 | *
67 | * For OAuth grants from client_credentials (i.e. Resource Owner: client)
68 | * @Auth will always check, because user is never exists in auth
69 | */
70 | if (!$this->auth->check(false)) {
71 | $this->auth->authenticate($route->getAuthenticationProviders());
72 |
73 | $provider = $this->auth->getProviderUsed();
74 |
75 | /** @var OAuth2 $provider */
76 | if ($provider instanceof OAuth2) {
77 | // check oauth grant type
78 | if (!is_null($grant) && $provider->getResourceOwnerType() !== $grant) {
79 | throw new AccessDeniedException();
80 | }
81 | }
82 |
83 | // login user through Auth
84 | $user = $this->auth->getUser();
85 | if ($user instanceof User) {
86 | \Auth::login($user);
87 |
88 | event(new UserLoggedInEvent($user));
89 | }
90 | }
91 |
92 | return $next($request);
93 | }
94 | }
--------------------------------------------------------------------------------
/src/Someline/Api/Middleware/AutoRenewJwtToken.php:
--------------------------------------------------------------------------------
1 | auth->setRequest($request)->getToken()) {
23 | // valid for refresh
24 | if (is_jwt_token_valid_for_refresh($token)) {
25 | $newToken = refresh_jwt_token();
26 | if (!empty($newToken)) {
27 | // send the refreshed token back to the client
28 | $response->headers->set('Authorization', $newToken);
29 | }
30 | }
31 | }
32 |
33 | return $response;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Someline/Auth/AuthUserHelpers.php:
--------------------------------------------------------------------------------
1 | getAuthUser()->getUserId();
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/src/Someline/Base/Api/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | getKey();
77 | // }
78 |
79 | /**
80 | * Get current auth user
81 | *
82 | * @return User|null
83 | */
84 | public function getAuthUser()
85 | {
86 | $user = null;
87 | if ($this->api_auth()->check()) {
88 | $user = $this->api_auth()->user();
89 | } else if (\Auth::check()) {
90 | $user = \Auth::user();
91 | }
92 | return $user;
93 | }
94 |
95 | /**
96 | * Get current auth user_id
97 | *
98 | * @return mixed|null
99 | */
100 | public function getAuthUserId()
101 | {
102 | $user_id = null;
103 | $user = $this->getAuthUser();
104 | if ($user) {
105 | $user_id = $user->user_id;
106 | }
107 | return $user_id;
108 | }
109 |
110 | /**
111 | * Get current model's user_id
112 | *
113 | * @return mixed|null
114 | */
115 | public function getUserId()
116 | {
117 | return $this->user_id;
118 | }
119 |
120 | /**
121 | * Update the creation and update ips.
122 | *
123 | * @return void
124 | */
125 | protected function updateIps()
126 | {
127 | $ip = smart_get_client_ip();
128 |
129 | if (!$this->isDirty('updated_ip')) {
130 | $this->updated_ip = $ip;
131 | }
132 |
133 | if (!$this->exists && !$this->isDirty('created_ip')) {
134 | $this->created_ip = $ip;
135 | }
136 | }
137 |
138 | /**
139 | * Update the creation and update by users.
140 | *
141 | * @return void
142 | */
143 | protected function updateUsers()
144 | {
145 | $user_id = $this->getAuthUserId();
146 | if (!$this->validUserId($user_id)) {
147 | return;
148 | }
149 |
150 | if (!$this->isDirty('updated_by')) {
151 | $this->updated_by = $user_id;
152 | }
153 |
154 | if (!$this->exists && !$this->isDirty('created_by')) {
155 | $this->created_by = $user_id;
156 | }
157 | }
158 |
159 | /**
160 | * @return bool
161 | */
162 | public function isAuthUserOwner(): bool
163 | {
164 | return $this->getAuthUserId() == $this->getUserId();
165 | }
166 |
167 | /**
168 | * @return Carbon
169 | */
170 | public function getNowTime()
171 | {
172 | return Carbon::now(app_timezone());
173 | }
174 |
175 | /**
176 | * @return Carbon
177 | */
178 | public function getNowUTCTime()
179 | {
180 | return Carbon::now('UTC');
181 | }
182 |
183 | /**
184 | * @return Carbon
185 | */
186 | public function getNowAuthUserTime()
187 | {
188 | return Carbon::now($this->getAuthUserDateTimezone());
189 | }
190 |
191 | /**
192 | * @return User|null
193 | */
194 | public function getUser()
195 | {
196 | return $this->user;
197 | }
198 |
199 | /**
200 | * @return User|null
201 | */
202 | public function getRelatedUser()
203 | {
204 | return $this->related_user;
205 | }
206 |
207 | /**
208 | * Set Model Presenter
209 | * @return $this
210 | * @throws \Exception
211 | */
212 | public function setModelPresenter()
213 | {
214 | $this->setPresenter(new ModelFractalPresenter());
215 | return $this;
216 | }
217 |
218 | /**
219 | * Return a timezone for all Datetime objects
220 | *
221 | * @return mixed
222 | */
223 | public function getAuthUserDateTimezone()
224 | {
225 | $user = $this->getAuthUser();
226 | if ($user && !empty($user->timezone)) {
227 | return $user->timezone;
228 | } else {
229 | return app_timezone();
230 | }
231 | }
232 |
233 | /**
234 | * Set a given attribute on the model.
235 | *
236 | *
237 | * @param string $key
238 | * @param mixed $value
239 | * @return $this
240 | */
241 | public function setAttribute($key, $value)
242 | {
243 |
244 | if ($this->timestamp_always_save_in_utc) {
245 | // set to UTC only if Carbon
246 | if ($value instanceof Carbon) {
247 | $value->setTimezone('UTC');
248 | }
249 | }
250 |
251 | return parent::setAttribute($key, $value);
252 | }
253 |
254 | /**
255 | * Get a plain attribute (not a relationship).
256 | *
257 | * @param string $key
258 | * @return mixed
259 | */
260 | public function getAttributeValue($key)
261 | {
262 | $value = parent::getAttributeValue($key);
263 |
264 | if ($value instanceof Carbon && $this->timestamp_get_with_user_timezone) {
265 | $value->setTimezone($this->getAuthUserDateTimezone());
266 | }
267 |
268 | return $value;
269 | }
270 |
271 | /**
272 | * Prepare a date for array / JSON serialization.
273 | *
274 | * @param \DateTimeInterface $date
275 | * @return string
276 | */
277 | protected function serializeDate(\DateTimeInterface $date)
278 | {
279 | if ($date instanceof Carbon && $this->timestamp_get_with_user_timezone) {
280 | $date->setTimezone($this->getAuthUserDateTimezone());
281 | }
282 | return $date->format($this->getDateFormat());
283 | }
284 |
285 | /**
286 | * @return mixed|Carbon
287 | */
288 | public function getCreatedAt()
289 | {
290 | return $this->created_at;
291 | }
292 |
293 | /**
294 | * @return mixed|Carbon
295 | */
296 | public function getUpdatedAt()
297 | {
298 | return $this->updated_at;
299 | }
300 |
301 | }
--------------------------------------------------------------------------------
/src/Someline/Base/Policies/Policy.php:
--------------------------------------------------------------------------------
1 | getUserId() == $user->getUserId();
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/Someline/Base/Presenters/Presenter.php:
--------------------------------------------------------------------------------
1 | resource = $this->transformCollection($data);
35 | } elseif ($data instanceof AbstractPaginator) {
36 | $this->resource = $this->transformPaginator($data);
37 | } else {
38 | $this->resource = $this->transformItem($data);
39 | }
40 |
41 | // set meta
42 | $this->resource->setMeta($this->meta);
43 |
44 | return $this->fractal->createData($this->resource)->toArray();
45 | }
46 |
47 | /**
48 | * @param array $meta
49 | */
50 | public function setMeta(array $meta)
51 | {
52 | $this->meta = $meta;
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Someline/Base/Repositories/Eloquent/Repository.php:
--------------------------------------------------------------------------------
1 | pushCriteria(new AuthUserCriteria());
41 | return $this;
42 | }
43 |
44 | public function byUsers($userIds)
45 | {
46 | $this->pushCriteria(new OwnerUsersCriteria($userIds));
47 | return $this;
48 | }
49 |
50 | public function authUserId()
51 | {
52 | return current_auth_user()->user_id;
53 | }
54 |
55 | public function validateCreate(array $attributes)
56 | {
57 | if (!is_null($this->validator)) {
58 | $this->validator->with($attributes)
59 | ->passesOrFail(ValidatorInterface::RULE_CREATE);
60 | }
61 | }
62 |
63 | public function validateUpdate(array $attributes)
64 | {
65 | if (!is_null($this->validator)) {
66 | $this->validator->with($attributes)
67 | ->passesOrFail(ValidatorInterface::RULE_UPDATE);
68 | }
69 | }
70 |
71 | /**
72 | * @param $validator
73 | * @return $this
74 | */
75 | public function setValidator($validator)
76 | {
77 | $this->validator = $validator;
78 | return $this;
79 | }
80 |
81 | public function present($results)
82 | {
83 | return $this->parserResult($results);
84 | }
85 |
86 | /**
87 | * @param Model $relateModel
88 | * @return $this
89 | */
90 | public function setRelateModel(Model $relateModel)
91 | {
92 | $this->relateModel = $relateModel;
93 | if ($relateModel) {
94 | $this->makeModel();
95 | }
96 | return $this;
97 | }
98 |
99 | /**
100 | * @return Relation
101 | */
102 | public function relation()
103 | {
104 | return null;
105 | }
106 |
107 | /**
108 | * @return Model
109 | * @throws RepositoryException
110 | */
111 | public function makeModel()
112 | {
113 | $model = $this->relateModel ? $this->relation() : $this->app->make($this->model());
114 |
115 | if (!($model instanceof Model || $model instanceof Relation)) {
116 | throw new RepositoryException("Class " . get_class($model) . " must be an instance of Illuminate\\Database\\Eloquent\\Model");
117 | }
118 |
119 | return $this->model = $model;
120 | }
121 |
122 |
123 | /**
124 | * Retrieve data array for populate field select
125 | *
126 | * @param string $column
127 | * @param string|null $key
128 | *
129 | * @return \Illuminate\Support\Collection|array
130 | */
131 | public function lists($column, $key = null)
132 | {
133 | $this->applyCriteria();
134 | $this->applyScope();
135 |
136 | $lists = $this->model->lists($column, $key);
137 |
138 | $this->resetModel();
139 |
140 | return $lists;
141 | }
142 |
143 | /**
144 | * Retrieve all data of repository
145 | *
146 | * @param array $columns
147 | * @return mixed
148 | */
149 | public function all($columns = array('*'))
150 | {
151 | $this->applyCriteria();
152 | $this->applyScope();
153 |
154 | if ($this->model instanceof \Illuminate\Database\Eloquent\Builder
155 | || $this->model instanceof \Illuminate\Database\Eloquent\Relations\Relation
156 | ) {
157 | $results = $this->model->get($columns);
158 | } else {
159 | $results = $this->model->all($columns);
160 | }
161 |
162 | $this->resetModel();
163 |
164 | return $this->parserResult($results);
165 | }
166 |
167 |
168 | /**
169 | * Add a basic where clause to the model.
170 | *
171 | * @param string|array|\Closure $column
172 | * @param mixed $value
173 | * @return $this
174 | */
175 | protected function modelWhere($column, $value = null)
176 | {
177 | $this->model = $this->model->where($column, $value);
178 | return $this;
179 | }
180 |
181 | /**
182 | * @return \Prettus\Repository\Contracts\PresenterInterface
183 | */
184 | public function getPresenter()
185 | {
186 | return $this->presenter;
187 | }
188 |
189 | /**
190 | * @param array $meta
191 | */
192 | public function setPresenterMeta(array $meta)
193 | {
194 | if ($this->presenter instanceof Presenter) {
195 | $this->presenter->setMeta($meta);
196 | }
197 | }
198 |
199 | /**
200 | * @return bool
201 | */
202 | public function getIsSearchableForceAndWhere()
203 | {
204 | return $this->isSearchableForceAndWhere;
205 | }
206 |
207 | /**
208 | * Find data by where conditions
209 | *
210 | * @param array $where
211 | *
212 | * @return $this
213 | */
214 | public function where(array $where)
215 | {
216 | $this->applyCriteria();
217 | $this->applyScope();
218 |
219 | $this->applyConditions($where);
220 |
221 | return $this;
222 | }
223 |
224 | /**
225 | * Retrieve first data of repository with fail if not found
226 | *
227 | * @param array $columns
228 | *
229 | * @return mixed
230 | */
231 | public function firstOrFail($columns = ['*'])
232 | {
233 | $this->applyCriteria();
234 | $this->applyScope();
235 |
236 | $results = $this->model->firstOrFail($columns);
237 |
238 | $this->resetModel();
239 |
240 | return $this->parserResult($results);
241 | }
242 |
243 | /**
244 | * Where first
245 | *
246 | * @param array $where
247 | * @param array $columns
248 | * @return mixed
249 | */
250 | public function whereFirst(array $where, $columns = ['*'])
251 | {
252 | return $this->where($where)->firstOrFail($columns = ['*']);
253 | }
254 |
255 | /**
256 | * Use Model for custom usages
257 | *
258 | * @param callable $callback
259 | * @return $this
260 | */
261 | public function useModel(callable $callback)
262 | {
263 | $this->model = $callback($this->model);
264 | return $this;
265 | }
266 |
267 | /**
268 | * Remove all or passed registered global scopes.
269 | *
270 | * @param array|null $scopes
271 | * @return $this
272 | */
273 | public function withoutGlobalScopes(array $scopes = null)
274 | {
275 | $this->model = $this->model->withoutGlobalScopes($scopes);
276 | return $this;
277 | }
278 |
279 | /**
280 | * Pre Apply Criteria for usage
281 | */
282 | public function preApplyCriteria()
283 | {
284 | $this->applyCriteria();
285 | $this->skipCriteria(true);
286 | }
287 |
288 | }
--------------------------------------------------------------------------------
/src/Someline/Base/Repositories/Interfaces/RepositoryInterface.php:
--------------------------------------------------------------------------------
1 | user(false);
13 | $user = !empty($user) ? $user : \Auth::user();
14 | if (!$user || !($user instanceof \Someline\Model\Foundation\User)) {
15 | if ($throwException) {
16 | throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();
17 | }
18 | }
19 | return $user;
20 | }
21 |
22 | }
23 |
24 | if (!function_exists('auth_check')) {
25 |
26 | /**
27 | * @return boolean
28 | */
29 | function auth_check()
30 | {
31 | return \Auth::check();
32 | }
33 |
34 | }
35 |
36 | if (!function_exists('current_full_url')) {
37 |
38 | function current_full_url($withQueryString = true)
39 | {
40 | $url = \Request::url();
41 | $query = $withQueryString ? (isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : null) : null;
42 |
43 | if ($query) {
44 | $path = \Request::path();
45 | if (starts_with($query, $path . '&')) {
46 | $query = substr($query, strlen($path) + 1);
47 | } else if (starts_with($query, $path)) {
48 | $query = substr($query, strlen($path));
49 | }
50 | }
51 |
52 | $url = $query ? $url . '?' . $query : $url;
53 | return $url;
54 | }
55 |
56 | }
57 |
58 | if (!function_exists('smart_get_client_ip')) {
59 |
60 | /**
61 | * @return array|string
62 | */
63 | function smart_get_client_ip()
64 | {
65 | $request = request();
66 | $clientIp = $request->header('X-Client-Ip');
67 | if (empty($clientIp)) {
68 | $clientIp = $request->getClientIp(true);
69 | }
70 | return $clientIp;
71 | }
72 |
73 | }
74 |
75 | if (!function_exists('app_locale')) {
76 |
77 | function app_locale()
78 | {
79 | return \App::getLocale();
80 | }
81 |
82 | }
83 |
84 | if (!function_exists('app_timezone')) {
85 |
86 | /**
87 | * @return mixed
88 | */
89 | function app_timezone()
90 | {
91 | return \Config::get("app.timezone");
92 | }
93 |
94 | }
95 |
96 | if (!function_exists('jwt_token')) {
97 |
98 | /**
99 | * @return string|null
100 | */
101 | function jwt_token()
102 | {
103 | $jwt_token = \Session::get('jwt_token');
104 | if (is_jwt_token_valid_for_refresh($jwt_token, true)
105 | || (empty($jwt_token) && \Auth::check())
106 | ) {
107 | $refreshed_token = refresh_jwt_token();
108 | if (!empty($refreshed_token)) {
109 | $jwt_token = $refreshed_token;
110 | }
111 | }
112 | return $jwt_token;
113 | }
114 |
115 | }
116 |
117 | if (!function_exists('refresh_jwt_token')) {
118 |
119 | /**
120 | * @return string|null
121 | */
122 | function refresh_jwt_token()
123 | {
124 | $jwt_token = null;
125 | if (\Auth::check()) {
126 | $jwt_token = \JWTAuth::fromUser(current_auth_user());
127 | \Session::put('jwt_token', $jwt_token);
128 | }
129 | return $jwt_token;
130 | }
131 |
132 | }
133 |
134 | if (!function_exists('is_jwt_token_valid_for_refresh')) {
135 |
136 | /**
137 | * @param $token
138 | * @param bool $allowExpireRefresh
139 | * @return bool
140 | */
141 | function is_jwt_token_valid_for_refresh($token, $allowExpireRefresh = false)
142 | {
143 | $is_jwt_token_valid_for_refresh = false;
144 | try {
145 | $payload = \JWTAuth::getPayload($token);
146 | $exp = $payload->get('exp');
147 | $nbf = $payload->get('nbf');
148 | if ($exp > 0 && $nbf > 0) {
149 | $nowTime = \Carbon\Carbon::now('UTC');
150 | $expireTime = \Carbon\Carbon::createFromTimestampUTC($exp);
151 | $validTime = \Carbon\Carbon::createFromTimestampUTC($nbf);
152 |
153 | // if now time is after valid time
154 | if ($nowTime->gt($validTime)) {
155 | $minutesAfterValid = $nowTime->diffInMinutes($validTime);
156 | $minutesBeforeExpire = $nowTime->diffInMinutes($expireTime);
157 | $totalValidLength = $validTime->diffInMinutes($expireTime);
158 | $halfAmountOfMinutes = floor($totalValidLength / 2);
159 | if ($minutesAfterValid >= $halfAmountOfMinutes) {
160 | $is_jwt_token_valid_for_refresh = true;
161 | }
162 | }
163 | }
164 | } catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
165 | if ($allowExpireRefresh) {
166 | $is_jwt_token_valid_for_refresh = true;
167 | }
168 | } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
169 | }
170 | return $is_jwt_token_valid_for_refresh;
171 | }
172 |
173 | }
174 |
175 | if (!function_exists('phone_parse')) {
176 |
177 | /**
178 | * @param string $phone_number
179 | * @param string $country_code An ISO 3166-1 two letter country code
180 | * @return null|\libphonenumber\PhoneNumber
181 | */
182 | function phone_parse($phone_number, $country_code)
183 | {
184 | $phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
185 | try {
186 | $phoneNumberProto = $phoneUtil->parseAndKeepRawInput($phone_number, $country_code);
187 | return $phoneNumberProto;
188 | } catch (\libphonenumber\NumberParseException $e) {
189 | return null;
190 | }
191 | }
192 |
193 | }
194 |
195 | if (!function_exists('phone_model_from')) {
196 |
197 | /**
198 | * @param string $phone_number
199 | * @param string $country_code An ISO 3166-1 two letter country code
200 | * @return \Someline\Model\Basic\PhoneNumberModel
201 | */
202 | function phone_model_from($phone_number, $country_code)
203 | {
204 | return new \Someline\Model\Basic\PhoneNumberModel($phone_number, $country_code);
205 | }
206 |
207 | }
208 |
209 | if (!function_exists('ip_to_country_iso_code')) {
210 |
211 | function ip_to_country_iso_code($ip = null, $default_iso_code = 'US')
212 | {
213 | if (empty($ip)) {
214 | $ip = smart_get_client_ip();
215 | }
216 |
217 | $location = \GeoIP::getLocation($ip);
218 |
219 | // check if NOT returned default
220 | if ($location['default'] === false && !empty($location['iso_code'])) {
221 | return $location['iso_code'];
222 | } else if ($location['default'] === false && !empty($location['isoCode'])) {
223 | return $location['isoCode'];
224 | } else {
225 | return $default_iso_code;
226 | }
227 | }
228 |
229 | }
230 |
231 | if (!function_exists('collection_paginate')) {
232 |
233 | /**
234 | * @param \Illuminate\Support\Collection $collection
235 | * @param $perPage
236 | * @param string $pageName
237 | * @param null $page
238 | * @return \Illuminate\Pagination\LengthAwarePaginator
239 | */
240 | function collection_paginate(\Illuminate\Support\Collection $collection, $perPage, $pageName = 'page', $page = null)
241 | {
242 | $page = $page ?: \Illuminate\Pagination\Paginator::resolveCurrentPage($pageName);
243 |
244 | $results = $collection->forPage($page, $perPage);
245 |
246 | parse_str(request()->getQueryString(), $query);
247 | unset($query[$pageName]);
248 |
249 | return new \Illuminate\Pagination\LengthAwarePaginator($results, $collection->count(), $perPage, $page, [
250 | 'pageName' => $pageName,
251 | 'path' => \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPath(),
252 | 'query' => $query,
253 | ]
254 | );
255 | }
256 |
257 | }
258 |
259 | if (!function_exists('str_contains_ascii_only')) {
260 |
261 | function str_contains_ascii_only($string)
262 | {
263 | return (preg_match('%^[ -~]+$%', $string, $m));
264 | }
265 |
266 | }
267 |
268 | if (!function_exists('in_arrayi')) {
269 |
270 | function in_arrayi($needle, $haystack)
271 | {
272 | return in_array(strtolower($needle), array_map('strtolower', $haystack));
273 | }
274 |
275 | }
276 |
277 | if (!function_exists('str_random_except')) {
278 |
279 | /**
280 | * Generate a more truly "random" alpha-numeric string.
281 | *
282 | * @param int $length
283 | * @param array $excludes
284 | * @return string
285 | */
286 | function str_random_except($length = 16, $excludes = [])
287 | {
288 | $string = '';
289 | $excludes = array_merge(['/', '+', '='], $excludes);
290 |
291 | while (($len = strlen($string)) < $length) {
292 | $size = $length - $len;
293 |
294 | $bytes = random_bytes($size);
295 |
296 | $string .= substr(str_ireplace($excludes, '', base64_encode($bytes)), 0, $size);
297 | }
298 |
299 | return $string;
300 | }
301 |
302 | }
--------------------------------------------------------------------------------
/src/Someline/Model/Basic/CountryModel.php:
--------------------------------------------------------------------------------
1 | '+376',
28 | 'AE' => '+971',
29 | 'AF' => '+93',
30 | 'AG' => '+1268',
31 | 'AI' => '+1264',
32 | 'AL' => '+355',
33 | 'AM' => '+374',
34 | 'AO' => '+244',
35 | 'AR' => '+54',
36 | 'AT' => '+43',
37 | 'AU' => '+61',
38 | 'AW' => '+297',
39 | 'AZ' => '+994',
40 | 'BA' => '+387',
41 | 'BB' => '+1246',
42 | 'BD' => '+880',
43 | 'BE' => '+32',
44 | 'BF' => '+226',
45 | 'BG' => '+359',
46 | 'BH' => '+973',
47 | 'BI' => '+257',
48 | 'BJ' => '+229',
49 | 'BM' => '+1441',
50 | 'BN' => '+673',
51 | 'BO' => '+591',
52 | 'BQ' => '+599',
53 | 'BR' => '+55',
54 | 'BS' => '+1242',
55 | 'BT' => '+975',
56 | 'BW' => '+267',
57 | 'BY' => '+375',
58 | 'BZ' => '+501',
59 | 'CA' => '+1',
60 | 'CD' => '+243',
61 | 'CF' => '+236',
62 | 'CG' => '+242',
63 | 'CH' => '+41',
64 | 'CI' => '+225',
65 | 'CK' => '+682',
66 | 'CL' => '+56',
67 | 'CM' => '+237',
68 | 'CN' => '+86',
69 | 'CO' => '+57',
70 | 'CR' => '+506',
71 | 'CU' => '+53',
72 | 'CV' => '+238',
73 | 'CW' => '+599',
74 | 'CY' => '+357',
75 | 'CZ' => '+420',
76 | 'DE' => '+49',
77 | 'DJ' => '+253',
78 | 'DK' => '+45',
79 | 'DM' => '+1767',
80 | 'DO' => '+1809',
81 | 'DZ' => '+213',
82 | 'EC' => '+593',
83 | 'EE' => '+372',
84 | 'EG' => '+20',
85 | 'ES' => '+34',
86 | 'ET' => '+251',
87 | 'FI' => '+358',
88 | 'FJ' => '+679',
89 | 'FO' => '+298',
90 | 'FR' => '+33',
91 | 'GA' => '+241',
92 | 'GB' => '+44',
93 | 'GD' => '+1473',
94 | 'GE' => '+995',
95 | 'GF' => '+594',
96 | 'GH' => '+233',
97 | 'GI' => '+350',
98 | 'GL' => '+299',
99 | 'GM' => '+220',
100 | 'GN' => '+224',
101 | 'GP' => '+590',
102 | 'GQ' => '+240',
103 | 'GR' => '+30',
104 | 'GT' => '+502',
105 | 'GU' => '+1671',
106 | 'GW' => '+245',
107 | 'GY' => '+592',
108 | 'HK' => '+852',
109 | 'HN' => '+504',
110 | 'HR' => '+385',
111 | 'HT' => '+509',
112 | 'HU' => '+36',
113 | 'ID' => '+62',
114 | 'IE' => '+353',
115 | 'IL' => '+972',
116 | 'IN' => '+91',
117 | 'IQ' => '+964',
118 | 'IR' => '+98',
119 | 'IS' => '+354',
120 | 'IT' => '+39',
121 | 'JM' => '+1876',
122 | 'JO' => '+962',
123 | 'JP' => '+81',
124 | 'KE' => '+254',
125 | 'KG' => '+996',
126 | 'KH' => '+855',
127 | 'KI' => '+686',
128 | 'KM' => '+269',
129 | 'KN' => '+1869',
130 | 'KR' => '+82',
131 | 'KW' => '+965',
132 | 'KY' => '+1345',
133 | 'KZ' => '+7',
134 | 'LA' => '+856',
135 | 'LB' => '+961',
136 | 'LC' => '+1758',
137 | 'LI' => '+423',
138 | 'LK' => '+94',
139 | 'LR' => '+231',
140 | 'LS' => '+266',
141 | 'LT' => '+370',
142 | 'LU' => '+352',
143 | 'LV' => '+371',
144 | 'LY' => '+218',
145 | 'MA' => '+212',
146 | 'MC' => '+377',
147 | 'MD' => '+373',
148 | 'ME' => '+382',
149 | 'MG' => '+261',
150 | 'MK' => '+389',
151 | 'ML' => '+223',
152 | 'MM' => '+95',
153 | 'MN' => '+976',
154 | 'MO' => '+853',
155 | 'MQ' => '+596',
156 | 'MR' => '+222',
157 | 'MS' => '+1664',
158 | 'MT' => '+356',
159 | 'MU' => '+230',
160 | 'MV' => '+960',
161 | 'MW' => '+265',
162 | 'MX' => '+52',
163 | 'MY' => '+60',
164 | 'MZ' => '+258',
165 | 'NA' => '+264',
166 | 'NC' => '+687',
167 | 'NE' => '+227',
168 | 'NG' => '+234',
169 | 'NI' => '+505',
170 | 'NL' => '+31',
171 | 'NO' => '+47',
172 | 'NP' => '+977',
173 | 'NZ' => '+64',
174 | 'OM' => '+968',
175 | 'PA' => '+507',
176 | 'PE' => '+51',
177 | 'PF' => '+689',
178 | 'PG' => '+675',
179 | 'PH' => '+63',
180 | 'PK' => '+92',
181 | 'PL' => '+48',
182 | 'PM' => '+508',
183 | 'PR' => '+1787',
184 | 'PS' => '+970',
185 | 'PT' => '+351',
186 | 'PW' => '+680',
187 | 'PY' => '+595',
188 | 'QA' => '+974',
189 | 'RE' => '+262',
190 | 'RO' => '+40',
191 | 'RS' => '+381',
192 | 'RU' => '+7',
193 | 'RW' => '+250',
194 | 'SA' => '+966',
195 | 'SB' => '+677',
196 | 'SC' => '+248',
197 | 'SD' => '+249',
198 | 'SE' => '+46',
199 | 'SG' => '+65',
200 | 'SI' => '+386',
201 | 'SK' => '+421',
202 | 'SL' => '+232',
203 | 'SM' => '+378',
204 | 'SN' => '+221',
205 | 'SO' => '+252',
206 | 'SR' => '+597',
207 | 'SS' => '+211',
208 | 'ST' => '+239',
209 | 'SV' => '+503',
210 | 'SX' => '+1721',
211 | 'SY' => '+963',
212 | 'SZ' => '+268',
213 | 'TC' => '+1649',
214 | 'TD' => '+235',
215 | 'TG' => '+228',
216 | 'TH' => '+66',
217 | 'TJ' => '+992',
218 | 'TL' => '+670',
219 | 'TM' => '+993',
220 | 'TN' => '+216',
221 | 'TO' => '+676',
222 | 'TR' => '+90',
223 | 'TT' => '+1868',
224 | 'TW' => '+886',
225 | 'TZ' => '+255',
226 | 'UA' => '+380',
227 | 'UG' => '+256',
228 | 'US' => '+1',
229 | 'UY' => '+598',
230 | 'UZ' => '+998',
231 | 'VC' => '+1784',
232 | 'VE' => '+58',
233 | 'VG' => '+1284',
234 | 'VI' => '+1340',
235 | 'VN' => '+84',
236 | 'VU' => '+678',
237 | 'WS' => '+685',
238 | 'YE' => '+967',
239 | 'YT' => '+269',
240 | 'ZA' => '+27',
241 | 'ZM' => '+260',
242 | 'ZW' => '+263',
243 | ];
244 |
245 | public static $country_calling_codes = array(
246 | 'AF' => '+93',
247 | 'AX' => '+358',
248 | 'AL' => '+355',
249 | 'DZ' => '+213',
250 | 'AS' => '+1',
251 | 'AD' => '+376',
252 | 'AO' => '+244',
253 | 'AI' => '+1',
254 | 'AQ' => '+672',
255 | 'AG' => '+1',
256 | 'AR' => '+54',
257 | 'AM' => '+374',
258 | 'AW' => '+297',
259 | 'SH' => '+247',
260 | 'AU' => '+61',
261 | 'AT' => '+43',
262 | 'AZ' => '+994',
263 | 'BS' => '+1',
264 | 'BH' => '+973',
265 | 'BD' => '+880',
266 | 'BB' => '+1',
267 | 'BY' => '+375',
268 | 'BE' => '+32',
269 | 'BZ' => '+501',
270 | 'BJ' => '+229',
271 | 'BM' => '+1',
272 | 'BT' => '+975',
273 | 'BO' => '+591',
274 | 'BQ' => '+599',
275 | 'BA' => '+387',
276 | 'BW' => '+267',
277 | 'BV' => '+47',
278 | 'BR' => '+55',
279 | 'IO' => '+246',
280 | 'BN' => '+673',
281 | 'BG' => '+359',
282 | 'BF' => '+226',
283 | 'BI' => '+257',
284 | 'KH' => '+855',
285 | 'CM' => '+237',
286 | 'CA' => '+1',
287 | 'CV' => '+238',
288 | 'KY' => '+1',
289 | 'CF' => '+236',
290 | 'TD' => '+235',
291 | 'CL' => '+56',
292 | 'CN' => '+86',
293 | 'CX' => '+61',
294 | 'CC' => '+891',
295 | 'CO' => '+57',
296 | 'KM' => '+269',
297 | 'CD' => '+243',
298 | 'CG' => '+242',
299 | 'CK' => '+682',
300 | 'CR' => '+506',
301 | 'CI' => '+225',
302 | 'HR' => '+385',
303 | 'CU' => '+53',
304 | 'CW' => '+599',
305 | 'CY' => '+357',
306 | 'CZ' => '+420',
307 | 'DK' => '+45',
308 | 'DJ' => '+253',
309 | 'DM' => '+1',
310 | 'DO' => '+1',
311 | 'TL' => '+670',
312 | 'EC' => '+593',
313 | 'EG' => '+20',
314 | 'SV' => '+503',
315 | 'GQ' => '+240',
316 | 'ER' => '+291',
317 | 'EE' => '+372',
318 | 'ET' => '+251',
319 | 'FK' => '+500',
320 | 'FO' => '+298',
321 | 'FJ' => '+679',
322 | 'FI' => '+358',
323 | 'FR' => '+33',
324 | 'GF' => '+594',
325 | 'PF' => '+689',
326 | 'TF' => '+262',
327 | 'GA' => '+241',
328 | 'GM' => '+220',
329 | 'GE' => '+995',
330 | 'DE' => '+49',
331 | 'GH' => '+233',
332 | 'GI' => '+350',
333 | 'GR' => '+30',
334 | 'GL' => '+299',
335 | 'GD' => '+1',
336 | 'GP' => '+590',
337 | 'GU' => '+1',
338 | 'GT' => '+502',
339 | 'GG' => '+44',
340 | 'GN' => '+224',
341 | 'GW' => '+245',
342 | 'GY' => '+592',
343 | 'HT' => '+509',
344 | 'HM' => '+61',
345 | 'VA' => '+379',
346 | 'HN' => '+504',
347 | 'HK' => '+852',
348 | 'HU' => '+36',
349 | 'IS' => '+354',
350 | 'IN' => '+91',
351 | 'ID' => '+62',
352 | 'IQ' => '+964',
353 | 'IR' => '+98',
354 | 'IE' => '+353',
355 | 'IM' => '+44',
356 | 'IL' => '+972',
357 | 'IT' => '+39',
358 | 'JM' => '+1',
359 | 'JP' => '+81',
360 | 'JE' => '+44',
361 | 'JO' => '+962',
362 | 'KZ' => '+7',
363 | 'KE' => '+254',
364 | 'KI' => '+686',
365 | 'KP' => '+850',
366 | 'KR' => '+82',
367 | 'XK' => '+377',
368 | 'XK_2' => '381',
369 | 'XK_3' => '386',
370 | 'KW' => '+965',
371 | 'KG' => '+996',
372 | 'LA' => '+856',
373 | 'LV' => '+371',
374 | 'LB' => '+961',
375 | 'LS' => '+266',
376 | 'LR' => '+231',
377 | 'LY' => '+218',
378 | 'LI' => '+423',
379 | 'LT' => '+370',
380 | 'LU' => '+352',
381 | 'MO' => '+853',
382 | 'MK' => '+389',
383 | 'MG' => '+261',
384 | 'MW' => '+265',
385 | 'MY' => '+60',
386 | 'MV' => '+960',
387 | 'ML' => '+223',
388 | 'MT' => '+356',
389 | 'MH' => '+692',
390 | 'MQ' => '+596',
391 | 'MR' => '+222',
392 | 'MU' => '+230',
393 | 'YT' => '+262',
394 | 'MX' => '+52',
395 | 'FM' => '+691',
396 | 'MD' => '+373',
397 | 'MC' => '+377',
398 | 'MN' => '+976',
399 | 'ME' => '+382',
400 | 'MS' => '+1',
401 | 'MA' => '+212',
402 | 'MZ' => '+258',
403 | 'MM' => '+95',
404 | 'NA' => '+264',
405 | 'NR' => '+674',
406 | 'NL' => '+31',
407 | 'BQ' => '+599',
408 | 'NP' => '+977',
409 | 'NC' => '+687',
410 | 'NZ' => '+64',
411 | 'NI' => '+505',
412 | 'NE' => '+227',
413 | 'NG' => '+234',
414 | 'NU' => '+683',
415 | 'NF' => '+672',
416 | 'GB' => '+44',
417 | 'GB_2' => '+28',
418 | 'MP' => '+1',
419 | 'NO' => '+47',
420 | 'OM' => '+968',
421 | 'PK' => '+92',
422 | 'PW' => '+680',
423 | 'PS' => '+970',
424 | 'PA' => '+507',
425 | 'PG' => '+675',
426 | 'PY' => '+595',
427 | 'PE' => '+51',
428 | 'PH' => '+63',
429 | 'PN' => '+64',
430 | 'PL' => '+48',
431 | 'PT' => '+351',
432 | 'PR' => '+1',
433 | 'QA' => '+974',
434 | 'RE' => '+262',
435 | 'RO' => '+40',
436 | 'RU' => '+7',
437 | 'RW' => '+250',
438 | 'BL' => '+590',
439 | 'SH' => '+290',
440 | 'KN' => '+1',
441 | 'LC' => '+1',
442 | 'MF' => '+590',
443 | 'PM' => '+508',
444 | 'VC' => '+1',
445 | 'WS' => '+685',
446 | 'SM' => '+378',
447 | 'ST' => '+239',
448 | 'SA' => '+966',
449 | 'SN' => '+221',
450 | 'RS' => '+381',
451 | 'SC' => '+248',
452 | 'SL' => '+232',
453 | 'SX' => '+1',
454 | 'SG' => '+65',
455 | 'SK' => '+421',
456 | 'SI' => '+386',
457 | 'SB' => '+677',
458 | 'SO' => '+252',
459 | 'ZA' => '+27',
460 | 'GS' => '+500',
461 | 'SS' => '+211',
462 | 'ES' => '+34',
463 | 'LK' => '+94',
464 | 'SD' => '+249',
465 | 'SR' => '+597',
466 | 'SJ' => '+47',
467 | 'SZ' => '+268',
468 | 'SE' => '+46',
469 | 'CH' => '+41',
470 | 'SY' => '+963',
471 | 'TW' => '+886',
472 | 'TJ' => '+992',
473 | 'TZ' => '+255',
474 | 'TH' => '+66',
475 | 'TL' => '+670',
476 | 'TG' => '+228',
477 | 'TK' => '+690',
478 | 'TO' => '+676',
479 | 'TT' => '+1',
480 | 'TN' => '+216',
481 | 'TR' => '+90',
482 | 'TM' => '+993',
483 | 'TC' => '+1',
484 | 'TV' => '+688',
485 | 'UG' => '+256',
486 | 'UA' => '+380',
487 | 'AE' => '+971',
488 | 'GB' => '+44',
489 | 'US' => '+1',
490 | 'UM' => '+1',
491 | 'UY' => '+598',
492 | 'UZ' => '+998',
493 | 'VU' => '+678',
494 | 'VE' => '+58',
495 | 'VN' => '+84',
496 | 'VG' => '+1',
497 | 'VI' => '+1',
498 | 'WF' => '+681',
499 | 'EH' => '+212',
500 | 'YE' => '+967',
501 | 'ZM' => '+260',
502 | 'ZW' => '+263'
503 | );
504 |
505 | public static function countriesToString(array $countries)
506 | {
507 | if (empty($countries)) {
508 | return "";
509 | }
510 |
511 | return implode(',', $countries);
512 | }
513 |
514 | public static function countriesFromString($countries_string)
515 | {
516 | if (empty($countries_string)) {
517 | return [];
518 | }
519 |
520 | return explode(',', $countries_string);
521 | }
522 |
523 | public static function getCountryList(array $countries = null, $locale = 'en')
524 | {
525 | $country_list = Countries::getList($locale, 'php', 'cldr');
526 |
527 | if (empty($countries)) {
528 | return $country_list;
529 | } else {
530 | return array_intersect_key($country_list, array_flip($countries));
531 | }
532 | }
533 |
534 | public static function getCountryISOCodeList()
535 | {
536 | $country_list = self::getCountryList();
537 | $country_iso_list = array_keys($country_list);
538 | return $country_iso_list;
539 | }
540 |
541 | public static function getLocalizedCountryList(array $countries = null)
542 | {
543 | $locale = 'en';
544 | $app_locale = app_locale();
545 | if ($app_locale == 'cn') {
546 | $locale = 'zh';
547 | }
548 | return self::getCountryList($countries, $locale);
549 | }
550 |
551 | public static function getCountryCallingCodeList(array $countries = null)
552 | {
553 | // $country_calling_code_list = self::$country_calling_codes;
554 | $country_calling_code_list = self::$nexmo_supported_country_calling_codes;
555 |
556 | if (empty($countries)) {
557 | return $country_calling_code_list;
558 | } else {
559 | return array_intersect_key($country_calling_code_list, array_flip($countries));
560 | }
561 | }
562 |
563 | public static function getCountryInfo($country_code = null)
564 | {
565 | if (empty($country_code)) {
566 | $country_code = self::getCurrentUserCountry();
567 | }
568 |
569 | $countryInfoList = self::getCountryInfoIndexedList();
570 | if (isset($countryInfoList[$country_code])) {
571 | return $countryInfoList[$country_code];
572 | } else {
573 | return null;
574 | }
575 | }
576 |
577 | public static function getCountryInfoList()
578 | {
579 | $countryCallingCodeList = self::getCountryCallingCodeList();
580 | $country_iso_codes = array_keys($countryCallingCodeList);
581 | $country_list_en = self::getCountryList($country_iso_codes);
582 | $country_list_locale = self::getLocalizedCountryList($country_iso_codes);
583 | $country_info_list = [];
584 | foreach ($country_iso_codes as $country_iso_code) {
585 | $country_info = [];
586 | if (empty($country_list_en[$country_iso_code])
587 | || empty($country_list_locale[$country_iso_code])
588 | ) {
589 | continue;
590 | } else {
591 | $country_info['country_code'] = $country_iso_code;
592 | $country_info['name'] = $country_list_en[$country_iso_code];
593 | $country_info['locale_name'] = $country_list_locale[$country_iso_code];
594 | $country_info['combined_name'] = $country_info['country_code'] . ' ' . $country_info['name'];
595 | $country_info['calling_code'] = $countryCallingCodeList[$country_iso_code];
596 | $country_info_list[] = $country_info;
597 | }
598 | }
599 | return $country_info_list;
600 | }
601 |
602 | public static function getCountryInfoIndexedList()
603 | {
604 | $countryCallingCodeList = self::getCountryCallingCodeList();
605 | $country_iso_codes = array_keys($countryCallingCodeList);
606 | $country_list_en = self::getCountryList($country_iso_codes);
607 | $country_list_locale = self::getLocalizedCountryList($country_iso_codes);
608 | $country_info_list = [];
609 | foreach ($country_iso_codes as $country_iso_code) {
610 | $country_info = [];
611 | if (empty($country_list_en[$country_iso_code])
612 | || empty($country_list_locale[$country_iso_code])
613 | ) {
614 | continue;
615 | } else {
616 | $country_info['country_code'] = $country_iso_code;
617 | $country_info['name'] = $country_list_en[$country_iso_code];
618 | $country_info['locale_name'] = $country_list_locale[$country_iso_code];
619 | $country_info['combined_name'] = $country_info['country_code'] . ' ' . $country_info['name'];
620 | $country_info['calling_code'] = $countryCallingCodeList[$country_iso_code];
621 | $country_info_list[$country_iso_code] = $country_info;
622 | }
623 | }
624 | return $country_info_list;
625 | }
626 |
627 | public static function setCurrentUserCountry($country)
628 | {
629 | if (in_array($country, self::getCountryISOCodeList())) {
630 | \Session::put(self::CURRENT_USER_COUNTRY_KEY, $country);
631 | } else {
632 | \Log::warning("Invalid country [$country]");
633 | return false;
634 | }
635 | }
636 |
637 | public static function getCurrentUserCountry()
638 | {
639 | return \Session::get(self::CURRENT_USER_COUNTRY_KEY, self::$fallback_country);
640 | }
641 |
642 | }
--------------------------------------------------------------------------------
/src/Someline/Model/Basic/PhoneNumberModel.php:
--------------------------------------------------------------------------------
1 | 'FROM_DEFAULT_COUNTRY',
32 | CountryCodeSource::FROM_NUMBER_WITH_IDD => 'FROM_NUMBER_WITH_IDD',
33 | CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN => 'FROM_NUMBER_WITH_PLUS_SIGN',
34 | CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN => 'FROM_NUMBER_WITHOUT_PLUS_SIGN',
35 | ];
36 |
37 | private $phoneNumberTypesText = [
38 | PhoneNumberType::FIXED_LINE => 'FIXED_LINE',
39 | PhoneNumberType::FIXED_LINE_OR_MOBILE => 'FIXED_LINE_OR_MOBILE',
40 | PhoneNumberType::MOBILE => 'MOBILE',
41 | PhoneNumberType::EMERGENCY => 'EMERGENCY',
42 | PhoneNumberType::SHORT_CODE => 'SHORT_CODE',
43 | PhoneNumberType::UNKNOWN => 'UNKNOWN',
44 | ];
45 |
46 | /**
47 | * Fields from libphonenumber\PhoneNumber
48 | */
49 | public $country_code; // 65
50 | public $country_code_plus_sign; // +65
51 | public $national_number;
52 | public $extension;
53 | public $country_code_source; // 0
54 | public $country_code_source_text; // FROM_NUMBER_WITH_PLUS_SIGN
55 | public $preferred_domestic_carrier_code;
56 | public $raw_input;
57 | public $raw_input_country;
58 |
59 | /**
60 | * Validation Results
61 | */
62 | public $is_possible_number = false;
63 | public $is_valid_number = false;
64 | public $is_mobile_number = false;
65 | public $region_code_for_number; // SG
66 | public $number_type; // 1
67 | public $number_type_text; // MOBILE
68 |
69 | /**
70 | * From Formatting
71 | */
72 | public $format_e164; // +6590919293
73 | public $format_national; // 9091 9293
74 | public $format_international; // +65 9091 9293
75 | public $format_rfc3966; // tel:+65-9091-9293
76 |
77 | /**
78 | * From additional
79 | */
80 | public $description; // Singapore
81 | public $carrier_name; // M1
82 | public $timezones; // Asia/Singapore
83 |
84 | /**
85 | * PhoneNumberModel constructor.
86 | * @param string $phone_number
87 | * @param string $country_code An ISO 3166-1 two letter country code
88 | */
89 | public function __construct($phone_number, $country_code)
90 | {
91 | $this->phoneUtil = PhoneNumberUtil::getInstance();
92 |
93 | $this->phoneNumberProto = phone_parse($phone_number, $country_code);
94 |
95 | $this->raw_input_country = $country_code;
96 |
97 | $this->parse();
98 | }
99 |
100 | private function parse()
101 | {
102 | if ($this->phoneNumberProto) {
103 | // from phoneNumberProto
104 | $this->country_code = $this->phoneNumberProto->getCountryCode();
105 | $this->country_code_plus_sign = "+" . $this->country_code;
106 | $this->national_number = $this->phoneNumberProto->getNationalNumber();
107 | $this->extension = $this->phoneNumberProto->getExtension();
108 | $this->country_code_source = $this->phoneNumberProto->getCountryCodeSource();
109 | if (isset($this->countryCodeSourcesText[$this->country_code_source])) {
110 | $this->country_code_source_text = $this->countryCodeSourcesText[$this->country_code_source];
111 | }
112 | $this->raw_input = $this->phoneNumberProto->getRawInput();
113 | $this->preferred_domestic_carrier_code = $this->phoneNumberProto->getPreferredDomesticCarrierCode();
114 |
115 | // from validation
116 | $this->is_possible_number = $this->phoneUtil->isPossibleNumber($this->phoneNumberProto);
117 | $this->is_valid_number = $this->phoneUtil->isValidNumber($this->phoneNumberProto);
118 | $this->region_code_for_number = $this->phoneUtil->getRegionCodeForNumber($this->phoneNumberProto);
119 | $this->number_type = $this->phoneUtil->getNumberType($this->phoneNumberProto);
120 | $this->number_type_text = $this->phoneUtil->getNumberType($this->phoneNumberProto);
121 | if (isset($this->phoneNumberTypesText[$this->number_type])) {
122 | $this->number_type_text = $this->phoneNumberTypesText[$this->number_type];
123 | } else {
124 | $this->number_type_text = "OTHER";
125 | }
126 | $this->is_mobile_number = in_array($this->number_type, [
127 | PhoneNumberType::FIXED_LINE_OR_MOBILE,
128 | PhoneNumberType::MOBILE,
129 | ]);
130 |
131 | // from formatting
132 | $this->format_e164 = $this->phoneUtil->format($this->phoneNumberProto, PhoneNumberFormat::E164);
133 | $this->format_international = $this->phoneUtil->format($this->phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
134 | $this->format_national = $this->phoneUtil->format($this->phoneNumberProto, PhoneNumberFormat::NATIONAL);
135 | $this->format_rfc3966 = $this->phoneUtil->format($this->phoneNumberProto, PhoneNumberFormat::RFC3966);
136 |
137 | // from additional
138 | $phoneNumberOfflineGeocoder = PhoneNumberOfflineGeocoder::getInstance();
139 | $this->description = $phoneNumberOfflineGeocoder->getDescriptionForNumber($this->phoneNumberProto, 'en');
140 |
141 | $phoneNumberToCarrierMapper = PhoneNumberToCarrierMapper::getInstance();
142 | $this->carrier_name = $phoneNumberToCarrierMapper->getNameForNumber($this->phoneNumberProto, 'en');
143 |
144 | $phoneNumberToTimeZonesMapper = PhoneNumberToTimeZonesMapper::getInstance();
145 | $this->timezones = $phoneNumberToTimeZonesMapper->getTimeZonesForNumber($this->phoneNumberProto);
146 | }
147 | }
148 |
149 | public function isValid()
150 | {
151 | return $this->phoneNumberProto != null;
152 | }
153 |
154 | public function isValidNumberForRegion($country_code)
155 | {
156 | return $this->phoneUtil->isValidNumberForRegion($this->phoneNumber, $country_code);
157 | }
158 |
159 | public function isValidNumber()
160 | {
161 | return $this->is_valid_number;
162 | }
163 |
164 | public function isMobileNumber()
165 | {
166 | return $this->is_mobile_number;
167 | }
168 |
169 | public function __toString()
170 | {
171 | return (string)$this->phoneNumberProto;
172 | }
173 |
174 | public function equals(PhoneNumberModel $other)
175 | {
176 | if (empty($this->isValid()) || empty($other->isValid())) {
177 | return false;
178 | }
179 | return $this->phoneNumberProto->equals($other->phoneNumberProto);
180 | }
181 |
182 | public function toArray()
183 | {
184 | return [
185 | 'country_code' => $this->country_code,
186 | 'country_code_plus_sign' => $this->country_code_plus_sign,
187 | 'national_number' => $this->national_number,
188 | 'extension' => $this->extension,
189 | 'country_code_source' => $this->country_code_source,
190 | 'country_code_source_text' => $this->country_code_source_text,
191 | 'preferred_domestic_carrier_code' => $this->preferred_domestic_carrier_code,
192 | 'raw_input' => $this->raw_input,
193 | 'raw_input_country' => $this->raw_input_country,
194 |
195 | 'is_possible_number' => $this->is_possible_number,
196 | 'is_valid_number' => $this->is_valid_number,
197 | 'is_mobile_number' => $this->is_mobile_number,
198 | 'region_code_for_number' => $this->region_code_for_number,
199 | 'number_type' => $this->number_type,
200 | 'number_type_text' => $this->number_type_text,
201 |
202 | 'format_e164' => $this->format_e164,
203 | 'format_national' => $this->format_national,
204 | 'format_international' => $this->format_international,
205 | 'format_rfc3966' => $this->format_rfc3966,
206 |
207 | 'description' => $this->description,
208 | 'carrier_name' => $this->carrier_name,
209 | 'timezones' => $this->timezones,
210 | ];
211 | }
212 |
213 | }
--------------------------------------------------------------------------------
/src/Someline/Model/Foundation/User.php:
--------------------------------------------------------------------------------
1 | creating > created > saved
21 | * @UPDATE: saving > updating > updated > saved
22 | *
23 | */
24 | class BaseModelObserver
25 | {
26 | public function creating(BaseModelEventsInterface $model)
27 | {
28 | $model->onCreating();
29 | }
30 |
31 | public function created(BaseModelEventsInterface $model)
32 | {
33 | $model->onCreated();
34 | }
35 |
36 | public function updating(BaseModelEventsInterface $model)
37 | {
38 | $model->onUpdating();
39 | }
40 |
41 | public function updated(BaseModelEventsInterface $model)
42 | {
43 | $model->onUpdated();
44 | }
45 |
46 | public function saving(BaseModelEventsInterface $model)
47 | {
48 | $model->onSaving();
49 | }
50 |
51 | public function saved(BaseModelEventsInterface $model)
52 | {
53 | $model->onSaved();
54 | }
55 |
56 | public function deleting(BaseModelEventsInterface $model)
57 | {
58 | $model->onDeleting();
59 | }
60 |
61 | public function deleted(BaseModelEventsInterface $model)
62 | {
63 | $model->onDeleted();
64 | }
65 |
66 | public function restoring(BaseModelEventsInterface $model)
67 | {
68 | $model->onRestoring();
69 | }
70 |
71 | public function restored(BaseModelEventsInterface $model)
72 | {
73 | $model->onRestored();
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/src/Someline/Model/Traits/BaseModelEvents.php:
--------------------------------------------------------------------------------
1 | creating > created > saved
21 | * @UPDATE: saving > updating > updated > saved
22 | *
23 | */
24 | trait BaseModelEvents
25 | {
26 |
27 | protected static function boot()
28 | {
29 | parent::boot();
30 |
31 | /** @var Model $ModelName */
32 | $ModelName = get_called_class();
33 |
34 | // Setup event bindings...
35 | $ModelName::observe(new BaseModelObserver);
36 | }
37 |
38 | public function onCreating()
39 | {
40 |
41 | // auto set user id
42 | if ($this->autoUserId && empty($this->user_id)) {
43 | $user_id = $this->getAuthUserId();
44 | if ($this->validUserId($user_id)) {
45 | $this->user_id = $user_id;
46 | }
47 | }
48 |
49 | }
50 |
51 | public function onCreated()
52 | {
53 | }
54 |
55 | public function onUpdating()
56 | {
57 | }
58 |
59 | public function onUpdated()
60 | {
61 | }
62 |
63 | public function onSaving()
64 | {
65 |
66 | // update ips if true
67 | if ($this->ips) {
68 | $this->updateIps();
69 | }
70 |
71 | // update users if true
72 | if ($this->update_users) {
73 | $this->updateUsers();
74 | }
75 |
76 | }
77 |
78 | public function onSaved()
79 | {
80 | }
81 |
82 | public function onDeleting()
83 | {
84 | }
85 |
86 | public function onDeleted()
87 | {
88 | }
89 |
90 | public function onRestoring()
91 | {
92 | }
93 |
94 | public function onRestored()
95 | {
96 | }
97 |
98 | /**
99 | * check the $user_id is valid.
100 | *
101 | * @param int|string $user_id
102 | * @return bool
103 | */
104 | protected function validUserId($user_id): bool
105 | {
106 | if ('int' === $this->keyType)
107 | return $user_id > 0;
108 |
109 | if ('string' === $this->keyType)
110 | return strlen($user_id) > 0;
111 | }
112 |
113 | }
--------------------------------------------------------------------------------
/src/Someline/Presenters/BasicPresenter.php:
--------------------------------------------------------------------------------
1 | transformer = $transformer;
26 | }
27 |
28 | /**
29 | * Transformer
30 | *
31 | * @return \League\Fractal\TransformerAbstract
32 | */
33 | public function getTransformer()
34 | {
35 | if ($this->transformer) {
36 | return new $this->transformer();
37 | } else {
38 | return new BasicTransformer();
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/Someline/Repositories/Criteria/AuthUserCriteria.php:
--------------------------------------------------------------------------------
1 | where('user_id', '=', current_auth_user()->user_id);
18 | return $model;
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/src/Someline/Repositories/Criteria/OwnerUsersCriteria.php:
--------------------------------------------------------------------------------
1 | userIds = $userIds;
24 | }
25 |
26 | public function apply($model, RepositoryInterface $repository)
27 | {
28 | $model = $model->whereIn('user_id', $this->userIds);
29 | return $model;
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/src/Someline/Repositories/Criteria/RequestCriteria.php:
--------------------------------------------------------------------------------
1 | getFieldsSearchable();
28 | $search = $this->request->get(config('repository.criteria.params.search', 'search'), null);
29 | $searchFields = $this->request->get(config('repository.criteria.params.searchFields', 'searchFields'), null);
30 | $filter = $this->request->get(config('repository.criteria.params.filter', 'filter'), null);
31 | $orderBy = $this->request->get(config('repository.criteria.params.orderBy', 'orderBy'), null);
32 | $sortedBy = $this->request->get(config('repository.criteria.params.sortedBy', 'sortedBy'), 'asc');
33 | $with = $this->request->get(config('repository.criteria.params.with', 'with'), null);
34 | $sortedBy = !empty($sortedBy) ? $sortedBy : 'asc';
35 |
36 | if ($search && is_array($fieldsSearchable) && count($fieldsSearchable)) {
37 |
38 | $searchFields = is_array($searchFields) || is_null($searchFields) ? $searchFields : explode(';', $searchFields);
39 | $fields = $this->parserFieldsSearch($fieldsSearchable, $searchFields);
40 | $isFirstField = true;
41 | $searchData = $this->parserSearchData($search);
42 | $search = $this->parserSearchValue($search);
43 | $modelForceAndWhere = method_exists($repository, 'getIsSearchableForceAndWhere') ? $repository->getIsSearchableForceAndWhere() : false;
44 |
45 | $model = $model->where(function ($query) use ($fields, $search, $searchData, $isFirstField, $modelForceAndWhere) {
46 | /** @var Builder $query */
47 |
48 | foreach ($fields as $field => $condition) {
49 |
50 | if (is_numeric($field)) {
51 | $field = $condition;
52 | $condition = "=";
53 | }
54 |
55 | $value = null;
56 |
57 | $condition = trim(strtolower($condition));
58 |
59 | if (isset($searchData[$field])) {
60 | if ($condition == "like_raw") {
61 | $condition = "like";
62 | $value = $searchData[$field];
63 | } else if ($condition == "like_safe") {
64 | $condition = "like";
65 | if (str_contains_ascii_only($searchData[$field])) {
66 | $value = "%{$searchData[$field]}%";
67 | } else {
68 | $value = null;
69 | }
70 | } else {
71 | $value = ($condition == "like" || $condition == "ilike") ? "%{$searchData[$field]}%" : $searchData[$field];
72 | }
73 | } else {
74 | if (!is_null($search)) {
75 | if ($condition == "like_raw") {
76 | $condition = "like";
77 | $value = $searchData[$field];
78 | } else if ($condition == "like_safe") {
79 | $condition = "like";
80 | if (str_contains_ascii_only($search)) {
81 | $value = "%{$search}%";
82 | } else {
83 | $value = null;
84 | }
85 | } else {
86 | $value = ($condition == "like" || $condition == "ilike") ? "%{$search}%" : $search;
87 | }
88 | }
89 | }
90 |
91 | $relation = null;
92 | if (stripos($field, '.')) {
93 | $explode = explode('.', $field);
94 | $field = array_pop($explode);
95 | $relation = implode('.', $explode);
96 | }
97 | $modelTableName = $query->getModel()->getTable();
98 | if ($isFirstField || $modelForceAndWhere) {
99 | if (!is_null($value)) {
100 | if (!is_null($relation)) {
101 | $query->whereHas($relation, function ($query) use ($field, $condition, $value) {
102 | $query->where($field, $condition, $value);
103 | });
104 | } else {
105 | $query->where($modelTableName . '.' . $field, $condition, $value);
106 | }
107 | $isFirstField = false;
108 | }
109 | } else {
110 | if (!is_null($value)) {
111 | if (!is_null($relation)) {
112 | $query->orWhereHas($relation, function ($query) use ($field, $condition, $value) {
113 | $query->where($field, $condition, $value);
114 | });
115 | } else {
116 | $query->orWhere($modelTableName . '.' . $field, $condition, $value);
117 | }
118 | }
119 | }
120 | }
121 | });
122 | }
123 |
124 | if (isset($orderBy) && !empty($orderBy)) {
125 | $orderBys = explode(';', $orderBy); // products:product_id:product_id|products.name;updated_at,desc
126 | $originSortedBy = $sortedBy;
127 | foreach ($orderBys as $orderBy) {
128 | // split sorted by
129 | $splitSortedBy = explode(',', $orderBy);
130 | if (count($splitSortedBy) > 1) {
131 | $sortedBy = $splitSortedBy[1];
132 | } else {
133 | $sortedBy = $originSortedBy;
134 | }
135 | $orderBy = $splitSortedBy[0];
136 |
137 | // split joint
138 | $split = explode('|', $orderBy);
139 | if (count($split) > 1) {
140 | /*
141 | * ex.
142 | * products|description -> join products on current_table.product_id = products.id order by description
143 | *
144 | * products:custom_id|products.description -> join products on current_table.custom_id = products.id order
145 | * by products.description (in case both tables have same column name)
146 | */
147 | $table = $model->getModel()->getTable();
148 | $sortTable = $split[0];
149 | $sortColumn = $split[1];
150 |
151 | $sortTableKeyName = 'id';
152 | $split = explode(':', $sortTable);
153 | if (count($split) > 2) { // products:custom_id:products_table_custom_id|products.description
154 | $sortTable = $split[0];
155 | $keyName = $table . '.' . $split[1];
156 | $sortTableKeyName = $split[2];
157 | } else if (count($split) > 1) {
158 | $sortTable = $split[0];
159 | $keyName = $table . '.' . $split[1];
160 | } else {
161 | /*
162 | * If you do not define which column to use as a joining column on current table, it will
163 | * use a singular of a join table appended with _id
164 | *
165 | * ex.
166 | * products -> product_id
167 | */
168 | $prefix = rtrim($sortTable, 's');
169 | $keyName = $table . '.' . $prefix . '_id';
170 | }
171 |
172 | $model = $model
173 | ->leftJoin($sortTable, $keyName, '=', $sortTable . '.' . $sortTableKeyName)
174 | ->orderBy($sortColumn, $sortedBy)
175 | ->groupBy($keyName) // Prevent SQL Error: SELECT list is not in GROUP BY clause and contains nonaggregated column 'xxx' which is not functionally dependent on columns in GROUP BY clause;
176 | ->addSelect($table . '.*');
177 | } else {
178 | $model = $model->orderBy($orderBy, $sortedBy);
179 | }
180 | }
181 | }
182 |
183 | if (isset($filter) && !empty($filter)) {
184 | if (is_string($filter)) {
185 | $filter = explode(';', $filter);
186 | }
187 |
188 | $model = $model->select($filter);
189 | }
190 |
191 | if ($with) {
192 | $with = explode(';', $with);
193 | $model = $model->with($with);
194 | }
195 |
196 | return $model;
197 | }
198 |
199 | protected function parserFieldsSearch(array $fields = [], array $searchFields = null)
200 | {
201 | if (!is_null($searchFields) && count($searchFields)) {
202 | $acceptedConditions = config('repository.criteria.acceptedConditions', [
203 | '=',
204 | 'like',
205 | 'like_raw',
206 | ]);
207 | $originalFields = $fields;
208 | $fields = [];
209 |
210 | foreach ($searchFields as $index => $field) {
211 | $field_parts = explode(':', $field);
212 | $temporaryIndex = array_search($field_parts[0], $originalFields);
213 |
214 | if (count($field_parts) == 2) {
215 | if (in_array($field_parts[1], $acceptedConditions)) {
216 | unset($originalFields[$temporaryIndex]);
217 | $field = $field_parts[0];
218 | $condition = $field_parts[1];
219 | $originalFields[$field] = $condition;
220 | $searchFields[$index] = $field;
221 | }
222 | }
223 | }
224 |
225 | foreach ($originalFields as $field => $condition) {
226 | if (is_numeric($field)) {
227 | $field = $condition;
228 | $condition = "=";
229 | }
230 | if (in_array($field, $searchFields)) {
231 | $fields[$field] = $condition;
232 | }
233 | }
234 |
235 | if (count($fields) == 0) {
236 | throw new \Exception(trans('repository::criteria.fields_not_accepted', ['field' => implode(',', $searchFields)]));
237 | }
238 |
239 | }
240 |
241 | return $fields;
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/src/Someline/Repositories/PresenterRepository.php:
--------------------------------------------------------------------------------
1 | setTransformer($transformer);
28 | $this->presenter = $basicPresenter;
29 | $this->skipPresenter = $skipPresenter;
30 | }
31 |
32 | /**
33 | * @return bool
34 | */
35 | public function isSkipPresenter(): bool
36 | {
37 | return $this->skipPresenter;
38 | }
39 |
40 | /**
41 | * @param bool $skipPresenter
42 | */
43 | public function setSkipPresenter(bool $skipPresenter)
44 | {
45 | $this->skipPresenter = $skipPresenter;
46 | }
47 |
48 | /**
49 | * @return null
50 | */
51 | public function getPresenter()
52 | {
53 | return $this->presenter;
54 | }
55 |
56 | /**
57 | * @param null|PresenterInterface $presenter
58 | */
59 | public function setPresenter(PresenterInterface $presenter)
60 | {
61 | $this->presenter = $presenter;
62 | }
63 |
64 | /**
65 | * Wrapper result data
66 | *
67 | * @param mixed $result
68 | *
69 | * @return mixed
70 | */
71 | public function parserResult($result)
72 | {
73 | if ($this->presenter instanceof PresenterInterface) {
74 |
75 | if ($result instanceof Collection || $result instanceof LengthAwarePaginator) {
76 | $result->each(function ($model) {
77 | if ($model instanceof Presentable) {
78 | $model->setPresenter($this->presenter);
79 | }
80 |
81 | return $model;
82 | });
83 | } elseif ($result instanceof Presentable) {
84 | $result = $result->setPresenter($this->presenter);
85 | }
86 |
87 | if (!$this->skipPresenter) {
88 | return $this->presenter->present($result);
89 | }
90 | }
91 |
92 | return $result;
93 | }
94 |
95 | }
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/BindingsGenerator.php:
--------------------------------------------------------------------------------
1 | getPath());
30 | $repositoryInterface = '\\' . $this->getRepository() . "::class";
31 | $repositoryEloquent = '\\' . $this->getEloquentRepository() . "::class";
32 | \File::put($this->getPath(), str_replace($this->bindPlaceholder, "\$this->app->bind({$repositoryInterface}, $repositoryEloquent);" . PHP_EOL . ' ' . $this->bindPlaceholder, $provider));
33 | }
34 |
35 | /**
36 | * Get destination path for generated file.
37 | *
38 | * @return string
39 | */
40 | public function getPath()
41 | {
42 | return $this->getBasePath() . '/Providers/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '.php';
43 | }
44 |
45 | /**
46 | * Get base path of destination file.
47 | *
48 | * @return string
49 | */
50 | public function getBasePath()
51 | {
52 | return config('repository.generator.basePath', app_path());
53 | }
54 |
55 | /**
56 | * Get generator path config node.
57 | *
58 | * @return string
59 | */
60 | public function getPathConfigNode()
61 | {
62 | return 'provider';
63 | }
64 |
65 | /**
66 | * Gets repository full class name
67 | *
68 | * @return string
69 | */
70 | public function getRepository()
71 | {
72 | $repositoryGenerator = new RepositoryInterfaceGenerator([
73 | 'name' => $this->name,
74 | ]);
75 |
76 | $repository = $repositoryGenerator->getRootNamespace() . '\\' . $repositoryGenerator->getName();
77 |
78 | return str_replace([
79 | "\\",
80 | '/'
81 | ], '\\', $repository) . 'Repository';
82 | }
83 |
84 | /**
85 | * Gets eloquent repository full class name
86 | *
87 | * @return string
88 | */
89 | public function getEloquentRepository()
90 | {
91 | $repositoryGenerator = new RepositoryEloquentGenerator([
92 | 'name' => $this->name,
93 | ]);
94 |
95 | $repository = $repositoryGenerator->getRootNamespace() . '\\' . $repositoryGenerator->getName();
96 |
97 | return str_replace([
98 | "\\",
99 | '/'
100 | ], '\\', $repository) . 'RepositoryEloquent';
101 | }
102 |
103 | /**
104 | * Get root namespace.
105 | *
106 | * @return string
107 | */
108 | public function getRootNamespace()
109 | {
110 | return parent::getRootNamespace() . parent::getConfigGeneratorClassPath($this->getPathConfigNode());
111 | }
112 |
113 | /**
114 | * Get array replacements.
115 | *
116 | * @return array
117 | */
118 | public function getReplacements()
119 | {
120 |
121 | return array_merge(parent::getReplacements(), [
122 | 'repository' => $this->getRepository(),
123 | 'eloquent' => $this->getEloquentRepository(),
124 | 'placeholder' => $this->bindPlaceholder,
125 | ]);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/BindingsCommand.php:
--------------------------------------------------------------------------------
1 | $this->argument('name'),
47 | 'force' => $this->option('force'),
48 | ]);
49 | // generate repository service provider
50 | if (!file_exists($bindingGenerator->getPath())) {
51 | $this->call('make:provider', [
52 | 'name' => $bindingGenerator->getConfigGeneratorClassPath($bindingGenerator->getPathConfigNode()),
53 | ]);
54 | // placeholder to mark the place in file where to prepend repository bindings
55 | $provider = File::get($bindingGenerator->getPath());
56 | File::put($bindingGenerator->getPath(), vsprintf(str_replace('//', '%s', $provider), [
57 | '//',
58 | $bindingGenerator->bindPlaceholder
59 | ]));
60 | }
61 | $bindingGenerator->run();
62 | $this->info($this->type . ' created successfully.');
63 | } catch (FileAlreadyExistsException $e) {
64 | $this->error($this->type . ' already exists!');
65 |
66 | return false;
67 | }
68 | }
69 |
70 |
71 | /**
72 | * The array of command arguments.
73 | *
74 | * @return array
75 | */
76 | public function getArguments()
77 | {
78 | return [
79 | [
80 | 'name',
81 | InputArgument::REQUIRED,
82 | 'The name of model for which the controller is being generated.',
83 | null
84 | ],
85 | ];
86 | }
87 |
88 |
89 | /**
90 | * The array of command options.
91 | *
92 | * @return array
93 | */
94 | public function getOptions()
95 | {
96 | return [
97 | [
98 | 'force',
99 | 'f',
100 | InputOption::VALUE_NONE,
101 | 'Force the creation if file already exists.',
102 | null
103 | ],
104 | ];
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/CommandBase.php:
--------------------------------------------------------------------------------
1 | fire();
14 | }
15 |
16 | public function fire()
17 | {
18 | // ...
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/ControllerCommand.php:
--------------------------------------------------------------------------------
1 | call('make:request', [
46 | 'name' => $this->argument('name') . 'CreateRequest'
47 | ]);
48 | // Generate update request for controller
49 | $this->call('make:request', [
50 | 'name' => $this->argument('name') . 'UpdateRequest'
51 | ]);
52 |
53 | (new ControllerGenerator([
54 | 'name' => $this->argument('name'),
55 | 'force' => $this->option('force'),
56 | ]))->run();
57 | $this->info($this->type . ' created successfully.');
58 | } catch (FileAlreadyExistsException $e) {
59 | $this->error($this->type . ' already exists!');
60 |
61 | return false;
62 | }
63 | }
64 |
65 |
66 | /**
67 | * The array of command arguments.
68 | *
69 | * @return array
70 | */
71 | public function getArguments()
72 | {
73 | return [
74 | [
75 | 'name',
76 | InputArgument::REQUIRED,
77 | 'The name of model for which the controller is being generated.',
78 | null
79 | ],
80 | ];
81 | }
82 |
83 |
84 | /**
85 | * The array of command options.
86 | *
87 | * @return array
88 | */
89 | public function getOptions()
90 | {
91 | return [
92 | [
93 | 'force',
94 | 'f',
95 | InputOption::VALUE_NONE,
96 | 'Force the creation if file already exists.',
97 | null
98 | ],
99 | ];
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/CriteriaCommand.php:
--------------------------------------------------------------------------------
1 | $this->argument('name'),
43 | 'force' => $this->option('force'),
44 | ]))->run();
45 |
46 | $this->info("Criteria created successfully.");
47 | } catch (FileAlreadyExistsException $ex) {
48 | $this->error($this->type . ' already exists!');
49 | return false;
50 | }
51 | }
52 |
53 | /**
54 | * The array of command arguments.
55 | *
56 | * @return array
57 | */
58 | public function getArguments()
59 | {
60 | return [
61 | [
62 | 'name',
63 | InputArgument::REQUIRED,
64 | 'The name of class being generated.',
65 | null
66 | ],
67 | ];
68 | }
69 |
70 | /**
71 | * The array of command options.
72 | *
73 | * @return array
74 | */
75 | public function getOptions()
76 | {
77 | return [
78 | [
79 | 'force',
80 | 'f',
81 | InputOption::VALUE_NONE,
82 | 'Force the creation if file already exists.',
83 | null
84 | ],
85 | ];
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/EntityCommand.php:
--------------------------------------------------------------------------------
1 | option('presenter');
41 | if (is_null($presenter) && $this->confirm('Would you like to create a Presenter? [y|N]')) {
42 | $presenter = 'yes';
43 | }
44 |
45 | if ($presenter == 'yes') {
46 | $this->call('starter:presenter', [
47 | 'name' => $this->argument('name'),
48 | '--force' => $this->option('force'),
49 | ]);
50 | }
51 |
52 | $validator = $this->option('validator');
53 | if (is_null($validator) && $this->confirm('Would you like to create a Validator? [y|N]')) {
54 | $validator = 'yes';
55 | }
56 |
57 | if ($validator == 'yes') {
58 | $this->call('starter:validator', [
59 | 'name' => $this->argument('name'),
60 | '--rules' => $this->option('rules'),
61 | '--force' => $this->option('force'),
62 | ]);
63 | }
64 |
65 | if ($this->confirm('Would you like to create a Controller? [y|N]')) {
66 |
67 | // Generate a controller resource
68 | $this->call('starter:controller', [
69 | 'name' => $this->argument('name'),
70 | '--force' => $this->option('force')
71 | ]);
72 | }
73 |
74 | $this->call('starter:repository', [
75 | 'name' => $this->argument('name'),
76 | '--fillable' => $this->option('fillable'),
77 | '--rules' => $this->option('rules'),
78 | '--validator' => $validator,
79 | '--presenter' => $presenter,
80 | '--force' => $this->option('force')
81 | ]);
82 |
83 | $this->call('starter:bindings', [
84 | 'name' => $this->argument('name'),
85 | '--force' => $this->option('force')
86 | ]);
87 | }
88 |
89 |
90 | /**
91 | * The array of command arguments.
92 | *
93 | * @return array
94 | */
95 | public function getArguments()
96 | {
97 | return [
98 | [
99 | 'name',
100 | InputArgument::REQUIRED,
101 | 'The name of class being generated.',
102 | null
103 | ],
104 | ];
105 | }
106 |
107 |
108 | /**
109 | * The array of command options.
110 | *
111 | * @return array
112 | */
113 | public function getOptions()
114 | {
115 | return [
116 | [
117 | 'fillable',
118 | null,
119 | InputOption::VALUE_OPTIONAL,
120 | 'The fillable attributes.',
121 | null
122 | ],
123 | [
124 | 'rules',
125 | null,
126 | InputOption::VALUE_OPTIONAL,
127 | 'The rules of validation attributes.',
128 | null
129 | ],
130 | [
131 | 'validator',
132 | null,
133 | InputOption::VALUE_OPTIONAL,
134 | 'Adds validator reference to the repository.',
135 | null
136 | ],
137 | [
138 | 'presenter',
139 | null,
140 | InputOption::VALUE_OPTIONAL,
141 | 'Adds presenter reference to the repository.',
142 | null
143 | ],
144 | [
145 | 'force',
146 | 'f',
147 | InputOption::VALUE_NONE,
148 | 'Force the creation if file already exists.',
149 | null
150 | ]
151 | ];
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/PresenterCommand.php:
--------------------------------------------------------------------------------
1 | $this->argument('name'),
47 | 'force' => $this->option('force'),
48 | ]))->run();
49 | $this->info("Presenter created successfully.");
50 |
51 | if (!\File::exists(app_path() . '/Transformers/' . $this->argument('name') . 'Transformer.php')) {
52 | if ($this->confirm('Would you like to create a Transformer? [y|N]')) {
53 | (new TransformerGenerator([
54 | 'name' => $this->argument('name'),
55 | 'force' => $this->option('force'),
56 | ]))->run();
57 | $this->info("Transformer created successfully.");
58 | }
59 | }
60 | } catch (FileAlreadyExistsException $e) {
61 | $this->error($this->type . ' already exists!');
62 |
63 | return false;
64 | }
65 | }
66 |
67 |
68 | /**
69 | * The array of command arguments.
70 | *
71 | * @return array
72 | */
73 | public function getArguments()
74 | {
75 | return [
76 | [
77 | 'name',
78 | InputArgument::REQUIRED,
79 | 'The name of model for which the presenter is being generated.',
80 | null
81 | ],
82 | ];
83 | }
84 |
85 |
86 | /**
87 | * The array of command options.
88 | *
89 | * @return array
90 | */
91 | public function getOptions()
92 | {
93 | return [
94 | [
95 | 'force',
96 | 'f',
97 | InputOption::VALUE_NONE,
98 | 'Force the creation if file already exists.',
99 | null
100 | ]
101 | ];
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/RepositoryCommand.php:
--------------------------------------------------------------------------------
1 | generators = new Collection();
52 |
53 | $this->generators->push(new MigrationGenerator([
54 | 'name' => 'create_' . snake_case(str_plural($this->argument('name'))) . '_table',
55 | 'fields' => $this->option('fillable'),
56 | 'force' => $this->option('force'),
57 | ]));
58 |
59 | $modelGenerator = new ModelGenerator([
60 | 'name' => $this->argument('name'),
61 | 'fillable' => $this->option('fillable'),
62 | 'force' => $this->option('force')
63 | ]);
64 |
65 | $this->generators->push($modelGenerator);
66 |
67 | $this->generators->push(new RepositoryInterfaceGenerator([
68 | 'name' => $this->argument('name'),
69 | 'force' => $this->option('force'),
70 | ]));
71 |
72 | foreach ($this->generators as $generator) {
73 | $generator->run();
74 | }
75 |
76 | $model = $modelGenerator->getRootNamespace() . '\\' . $modelGenerator->getName();
77 | $model = str_replace([
78 | "\\",
79 | '/'
80 | ], '\\', $model);
81 |
82 | try {
83 | (new RepositoryEloquentGenerator([
84 | 'name' => $this->argument('name'),
85 | 'rules' => $this->option('rules'),
86 | 'validator' => $this->option('validator'),
87 | 'presenter' => $this->option('presenter'),
88 | 'force' => $this->option('force'),
89 | 'model' => $model
90 | ]))->run();
91 | $this->info("Repository created successfully.");
92 | } catch (FileAlreadyExistsException $e) {
93 | $this->error($this->type . ' already exists!');
94 |
95 | return false;
96 | }
97 | }
98 |
99 |
100 | /**
101 | * The array of command arguments.
102 | *
103 | * @return array
104 | */
105 | public function getArguments()
106 | {
107 | return [
108 | [
109 | 'name',
110 | InputArgument::REQUIRED,
111 | 'The name of class being generated.',
112 | null
113 | ],
114 | ];
115 | }
116 |
117 |
118 | /**
119 | * The array of command options.
120 | *
121 | * @return array
122 | */
123 | public function getOptions()
124 | {
125 | return [
126 | [
127 | 'fillable',
128 | null,
129 | InputOption::VALUE_OPTIONAL,
130 | 'The fillable attributes.',
131 | null
132 | ],
133 | [
134 | 'rules',
135 | null,
136 | InputOption::VALUE_OPTIONAL,
137 | 'The rules of validation attributes.',
138 | null
139 | ],
140 | [
141 | 'validator',
142 | null,
143 | InputOption::VALUE_OPTIONAL,
144 | 'Adds validator reference to the repository.',
145 | null
146 | ],
147 | [
148 | 'presenter',
149 | null,
150 | InputOption::VALUE_OPTIONAL,
151 | 'Adds presenter reference to the repository.',
152 | null
153 | ],
154 | [
155 | 'force',
156 | 'f',
157 | InputOption::VALUE_NONE,
158 | 'Force the creation if file already exists.',
159 | null
160 | ]
161 | ];
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/TransformerCommand.php:
--------------------------------------------------------------------------------
1 | $this->argument('name'),
45 | 'force' => $this->option('force'),
46 | ]))->run();
47 | $this->info("Transformer created successfully.");
48 | } catch (FileAlreadyExistsException $e) {
49 | $this->error($this->type . ' already exists!');
50 |
51 | return false;
52 | }
53 | }
54 |
55 |
56 | /**
57 | * The array of command arguments.
58 | *
59 | * @return array
60 | */
61 | public function getArguments()
62 | {
63 | return [
64 | [
65 | 'name',
66 | InputArgument::REQUIRED,
67 | 'The name of model for which the transformer is being generated.',
68 | null
69 | ],
70 | ];
71 | }
72 |
73 | /**
74 | * The array of command options.
75 | *
76 | * @return array
77 | */
78 | public function getOptions()
79 | {
80 | return [
81 | [
82 | 'force',
83 | 'f',
84 | InputOption::VALUE_NONE,
85 | 'Force the creation if file already exists.',
86 | null
87 | ]
88 | ];
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Commands/ValidatorCommand.php:
--------------------------------------------------------------------------------
1 | $this->argument('name'),
46 | 'rules' => $this->option('rules'),
47 | 'force' => $this->option('force'),
48 | ]))->run();
49 | $this->info("Validator created successfully.");
50 | } catch (FileAlreadyExistsException $e) {
51 | $this->error($this->type . ' already exists!');
52 |
53 | return false;
54 | }
55 | }
56 |
57 |
58 | /**
59 | * The array of command arguments.
60 | *
61 | * @return array
62 | */
63 | public function getArguments()
64 | {
65 | return [
66 | [
67 | 'name',
68 | InputArgument::REQUIRED,
69 | 'The name of model for which the validator is being generated.',
70 | null
71 | ],
72 | ];
73 | }
74 |
75 |
76 | /**
77 | * The array of command options.
78 | *
79 | * @return array
80 | */
81 | public function getOptions()
82 | {
83 | return [
84 | [
85 | 'rules',
86 | null,
87 | InputOption::VALUE_OPTIONAL,
88 | 'The rules of validation attributes.',
89 | null
90 | ],
91 | [
92 | 'force',
93 | 'f',
94 | InputOption::VALUE_NONE,
95 | 'Force the creation if file already exists.',
96 | null
97 | ],
98 | ];
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/ControllerGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode()));
26 | }
27 |
28 | /**
29 | * Get generator path config node.
30 | *
31 | * @return string
32 | */
33 | public function getPathConfigNode()
34 | {
35 | return 'controllers';
36 | }
37 |
38 | /**
39 | * Get destination path for generated file.
40 | *
41 | * @return string
42 | */
43 | public function getPath()
44 | {
45 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getControllerName() . 'Controller.php';
46 | }
47 |
48 | /**
49 | * Get base path of destination file.
50 | *
51 | * @return string
52 | */
53 | public function getBasePath()
54 | {
55 | return config('repository.generator.basePath', app_path());
56 | }
57 |
58 | /**
59 | * Gets controller name based on model
60 | *
61 | * @return string
62 | */
63 | public function getControllerName()
64 | {
65 |
66 | return ucfirst($this->getPluralName());
67 | }
68 |
69 | /**
70 | * Gets plural name based on model
71 | *
72 | * @return string
73 | */
74 | public function getPluralName()
75 | {
76 |
77 | return str_plural(lcfirst(ucwords($this->getClass())));
78 | }
79 |
80 | /**
81 | * Get array replacements.
82 | *
83 | * @return array
84 | */
85 | public function getReplacements()
86 | {
87 |
88 | return array_merge(parent::getReplacements(), [
89 | 'controller' => $this->getControllerName(),
90 | 'plural' => $this->getPluralName(),
91 | 'singular' => $this->getSingularName(),
92 | 'validator' => $this->getValidator(),
93 | 'repository' => $this->getRepository(),
94 | 'appname' => $this->getAppNamespace(),
95 | ]);
96 | }
97 |
98 | /**
99 | * Gets singular name based on model
100 | *
101 | * @return string
102 | */
103 | public function getSingularName()
104 | {
105 | return str_singular(lcfirst(ucwords($this->getClass())));
106 | }
107 |
108 | /**
109 | * Gets validator full class name
110 | *
111 | * @return string
112 | */
113 | public function getValidator()
114 | {
115 | $validatorGenerator = new ValidatorGenerator([
116 | 'name' => $this->name,
117 | ]);
118 |
119 | $validator = $validatorGenerator->getRootNamespace() . '\\' . $validatorGenerator->getName();
120 |
121 | return 'use ' . str_replace([
122 | "\\",
123 | '/'
124 | ], '\\', $validator) . 'Validator;';
125 | }
126 |
127 |
128 | /**
129 | * Gets repository full class name
130 | *
131 | * @return string
132 | */
133 | public function getRepository()
134 | {
135 | $repositoryGenerator = new RepositoryInterfaceGenerator([
136 | 'name' => $this->name,
137 | ]);
138 |
139 | $repository = $repositoryGenerator->getRootNamespace() . '\\' . $repositoryGenerator->getName();
140 |
141 | return 'use ' . str_replace([
142 | "\\",
143 | '/'
144 | ], '\\', $repository) . 'Repository;';
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/CriteriaGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
26 | }
27 |
28 | /**
29 | * Get generator path config node.
30 | * @return string
31 | */
32 | public function getPathConfigNode()
33 | {
34 | return 'criteria';
35 | }
36 |
37 | /**
38 | * Get destination path for generated file.
39 | *
40 | * @return string
41 | */
42 | public function getPath()
43 | {
44 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . 'Criteria.php';
45 | }
46 |
47 | /**
48 | * Get base path of destination file.
49 | *
50 | * @return string
51 | */
52 | public function getBasePath()
53 | {
54 | return config('repository.generator.basePath', app_path());
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/FileAlreadyExistsException.php:
--------------------------------------------------------------------------------
1 | filesystem = new Filesystem;
44 | $this->options = $options;
45 | }
46 |
47 |
48 | /**
49 | * Get the filesystem instance.
50 | *
51 | * @return \Illuminate\Filesystem\Filesystem
52 | */
53 | public function getFilesystem()
54 | {
55 | return $this->filesystem;
56 | }
57 |
58 |
59 | /**
60 | * Set the filesystem instance.
61 | *
62 | * @param \Illuminate\Filesystem\Filesystem $filesystem
63 | *
64 | * @return $this
65 | */
66 | public function setFilesystem(Filesystem $filesystem)
67 | {
68 | $this->filesystem = $filesystem;
69 |
70 | return $this;
71 | }
72 |
73 |
74 | /**
75 | * Get stub template for generated file.
76 | *
77 | * @return string
78 | */
79 | public function getStub()
80 | {
81 | $path = config('repository.generator.stubsOverridePath', __DIR__);
82 |
83 | if(!file_exists($path . '/Stubs/' . $this->stub . '.stub')){
84 | $path = __DIR__;
85 | }
86 |
87 | return (new Stub($path . '/Stubs/' . $this->stub . '.stub', $this->getReplacements()))->render();
88 | }
89 |
90 |
91 | /**
92 | * Get template replacements.
93 | *
94 | * @return array
95 | */
96 | public function getReplacements()
97 | {
98 | return [
99 | 'class' => $this->getClass(),
100 | 'namespace' => $this->getNamespace(),
101 | 'root_namespace' => $this->getRootNamespace()
102 | ];
103 | }
104 |
105 |
106 | /**
107 | * Get base path of destination file.
108 | *
109 | * @return string
110 | */
111 | public function getBasePath()
112 | {
113 | return base_path();
114 | }
115 |
116 |
117 | /**
118 | * Get destination path for generated file.
119 | *
120 | * @return string
121 | */
122 | public function getPath()
123 | {
124 | return $this->getBasePath() . '/' . $this->getName() . '.php';
125 | }
126 |
127 |
128 | /**
129 | * Get name input.
130 | *
131 | * @return string
132 | */
133 | public function getName()
134 | {
135 | $name = $this->name;
136 | if (str_contains($this->name, '\\')) {
137 | $name = str_replace('\\', '/', $this->name);
138 | }
139 | if (str_contains($this->name, '/')) {
140 | $name = str_replace('/', '/', $this->name);
141 | }
142 |
143 | return Str::studly(str_replace(' ', '/', ucwords(str_replace('/', ' ', $name))));
144 | }
145 |
146 |
147 | /**
148 | * Get class name.
149 | *
150 | * @return string
151 | */
152 | public function getClass()
153 | {
154 | return Str::studly(class_basename($this->getName()));
155 | }
156 |
157 |
158 | /**
159 | * Get paths of namespace.
160 | *
161 | * @return array
162 | */
163 | public function getSegments()
164 | {
165 | return explode('/', $this->getName());
166 | }
167 |
168 |
169 | /**
170 | * Get root namespace.
171 | *
172 | * @return string
173 | */
174 | public function getRootNamespace()
175 | {
176 | return config('repository.generator.rootNamespace', $this->getAppNamespace());
177 | }
178 |
179 |
180 | /**
181 | * Get class-specific output paths.
182 | *
183 | * @param $class
184 | *
185 | * @return string
186 | */
187 | public function getConfigGeneratorClassPath($class, $directoryPath = false)
188 | {
189 | switch ($class) {
190 | case ('models' === $class):
191 | $path = config('repository.generator.paths.models', 'Entities');
192 | break;
193 | case ('repositories' === $class):
194 | $path = config('repository.generator.paths.repositories', 'Repositories');
195 | break;
196 | case ('interfaces' === $class):
197 | $path = config('repository.generator.paths.interfaces', 'Repositories');
198 | break;
199 | case ('presenters' === $class):
200 | $path = config('repository.generator.paths.presenters', 'Presenters');
201 | break;
202 | case ('transformers' === $class):
203 | $path = config('repository.generator.paths.transformers', 'Transformers');
204 | break;
205 | case ('validators' === $class):
206 | $path = config('repository.generator.paths.validators', 'Validators');
207 | break;
208 | case ('controllers' === $class):
209 | $path = config('repository.generator.paths.controllers', 'Http\Controllers');
210 | break;
211 | case ('provider' === $class):
212 | $path = config('repository.generator.paths.provider', 'RepositoryServiceProvider');
213 | break;
214 | case ('criteria' === $class):
215 | $path = config('repository.generator.paths.criteria', 'Criteria');
216 | break;
217 | default:
218 | $path = '';
219 | }
220 |
221 | if ($directoryPath) {
222 | $path = str_replace('\\', '/', $path);
223 | } else {
224 | $path = str_replace('/', '\\', $path);
225 | }
226 |
227 |
228 | return $path;
229 | }
230 |
231 |
232 | abstract public function getPathConfigNode();
233 |
234 |
235 | /**
236 | * Get class namespace.
237 | *
238 | * @return string
239 | */
240 | public function getNamespace()
241 | {
242 | $segments = $this->getSegments();
243 | array_pop($segments);
244 | $rootNamespace = $this->getRootNamespace();
245 | if ($rootNamespace == false) {
246 | return null;
247 | }
248 |
249 | return 'namespace ' . rtrim($rootNamespace . '\\' . implode($segments, '\\'), '\\') . ';';
250 | }
251 |
252 |
253 | /**
254 | * Setup some hook.
255 | *
256 | * @return void
257 | */
258 | public function setUp()
259 | {
260 | //
261 | }
262 |
263 |
264 | /**
265 | * Run the generator.
266 | *
267 | * @return int
268 | * @throws FileAlreadyExistsException
269 | */
270 | public function run()
271 | {
272 | $this->setUp();
273 | if ($this->filesystem->exists($path = $this->getPath()) && !$this->force) {
274 | throw new FileAlreadyExistsException($path);
275 | }
276 | if (!$this->filesystem->isDirectory($dir = dirname($path))) {
277 | $this->filesystem->makeDirectory($dir, 0777, true, true);
278 | }
279 |
280 | return $this->filesystem->put($path, $this->getStub());
281 | }
282 |
283 |
284 | /**
285 | * Get options.
286 | *
287 | * @return string
288 | */
289 | public function getOptions()
290 | {
291 | return $this->options;
292 | }
293 |
294 |
295 | /**
296 | * Determinte whether the given key exist in options array.
297 | *
298 | * @param string $key
299 | *
300 | * @return boolean
301 | */
302 | public function hasOption($key)
303 | {
304 | return array_key_exists($key, $this->options);
305 | }
306 |
307 |
308 | /**
309 | * Get value from options by given key.
310 | *
311 | * @param string $key
312 | * @param string|null $default
313 | *
314 | * @return string
315 | */
316 | public function getOption($key, $default = null)
317 | {
318 | if (!$this->hasOption($key)) {
319 | return $default;
320 | }
321 |
322 | return $this->options[$key] ?: $default;
323 | }
324 |
325 |
326 | /**
327 | * Helper method for "getOption".
328 | *
329 | * @param string $key
330 | * @param string|null $default
331 | *
332 | * @return string
333 | */
334 | public function option($key, $default = null)
335 | {
336 | return $this->getOption($key, $default);
337 | }
338 |
339 |
340 | /**
341 | * Handle call to __get method.
342 | *
343 | * @param string $key
344 | *
345 | * @return string|mixed
346 | */
347 | public function __get($key)
348 | {
349 | if (property_exists($this, $key)) {
350 | return $this->{$key};
351 | }
352 |
353 | return $this->option($key);
354 | }
355 | }
356 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/MigrationGenerator.php:
--------------------------------------------------------------------------------
1 | getBasePath() . $this->getFileName() . '.php';
43 | }
44 |
45 |
46 | /**
47 | * Get generator path config node.
48 | *
49 | * @return string
50 | */
51 | public function getPathConfigNode()
52 | {
53 | return '';
54 | }
55 |
56 |
57 | /**
58 | * Get root namespace.
59 | *
60 | * @return string
61 | */
62 | public function getRootNamespace()
63 | {
64 | return '';
65 | }
66 |
67 |
68 | /**
69 | * Get migration name.
70 | *
71 | * @return string
72 | */
73 | public function getMigrationName()
74 | {
75 | return strtolower($this->name);
76 | }
77 |
78 |
79 | /**
80 | * Get file name.
81 | *
82 | * @return string
83 | */
84 | public function getFileName()
85 | {
86 | return date('Y_m_d_His_') . $this->getMigrationName();
87 | }
88 |
89 |
90 | /**
91 | * Get schema parser.
92 | *
93 | * @return SchemaParser
94 | */
95 | public function getSchemaParser()
96 | {
97 | return new SchemaParser($this->fields);
98 | }
99 |
100 |
101 | /**
102 | * Get name parser.
103 | *
104 | * @return NameParser
105 | */
106 | public function getNameParser()
107 | {
108 | return new NameParser($this->name);
109 | }
110 |
111 |
112 | /**
113 | * Get stub templates.
114 | *
115 | * @return string
116 | */
117 | public function getStub()
118 | {
119 | $parser = $this->getNameParser();
120 |
121 | $action = $parser->getAction();
122 | switch ($action) {
123 | case 'add':
124 | case 'append':
125 | case 'update':
126 | case 'insert':
127 | $file = 'change';
128 | $replacements = [
129 | 'class' => $this->getClass(),
130 | 'table' => $parser->getTable(),
131 | 'fields_up' => $this->getSchemaParser()->up(),
132 | 'fields_down' => $this->getSchemaParser()->down(),
133 | ];
134 | break;
135 |
136 | case 'delete':
137 | case 'remove':
138 | case 'alter':
139 | $file = 'change';
140 | $replacements = [
141 | 'class' => $this->getClass(),
142 | 'table' => $parser->getTable(),
143 | 'fields_down' => $this->getSchemaParser()->up(),
144 | 'fields_up' => $this->getSchemaParser()->down(),
145 | ];
146 | break;
147 | default:
148 | $file = 'create';
149 | $replacements = [
150 | 'class' => $this->getClass(),
151 | 'table_singular' => str_singular($parser->getTable()),
152 | 'table' => $parser->getTable(),
153 | 'fields' => $this->getSchemaParser()->up(),
154 | ];
155 | break;
156 | }
157 | $path = config('repository.generator.stubsOverridePath', __DIR__);
158 |
159 | if (!file_exists($path . "/Stubs/migration/{$file}.stub")) {
160 | $path = __DIR__;
161 | }
162 |
163 | if (!file_exists($path . "/Stubs/migration/{$file}.stub")) {
164 | throw new FileNotFoundException($path . "/Stubs/migration/{$file}.stub");
165 | }
166 |
167 | return Stub::create($path . "/Stubs/migration/{$file}.stub", $replacements);
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Migrations/NameParser.php:
--------------------------------------------------------------------------------
1 | [
29 | 'create',
30 | 'make'
31 | ],
32 | 'delete' => [
33 | 'delete',
34 | 'remove'
35 | ],
36 | 'add' => [
37 | 'add',
38 | 'update',
39 | 'append',
40 | 'insert'
41 | ],
42 | 'drop' => [
43 | 'destroy',
44 | 'drop'
45 | ]
46 | ];
47 |
48 | /**
49 | * The constructor.
50 | *
51 | * @param string $name
52 | */
53 | public function __construct($name)
54 | {
55 | $this->name = $name;
56 | $this->data = $this->fetchData();
57 | }
58 |
59 | /**
60 | * Fetch the migration name to an array data.
61 | *
62 | * @return array
63 | */
64 | protected function fetchData()
65 | {
66 | return explode('_', $this->name);
67 | }
68 |
69 | /**
70 | * Get original migration name.
71 | *
72 | * @return string
73 | */
74 | public function getOriginalName()
75 | {
76 | return $this->name;
77 | }
78 |
79 | /**
80 | * Get table name.
81 | *
82 | * @return string
83 | */
84 | public function getTable()
85 | {
86 | return $this->getTableName();
87 | }
88 |
89 | /**
90 | * Get the table will be used.
91 | *
92 | * @return string
93 | */
94 | public function getTableName()
95 | {
96 | $matches = array_reverse($this->getMatches());
97 |
98 | return array_shift($matches);
99 | }
100 |
101 | /**
102 | * Get matches data from regex.
103 | *
104 | * @return array
105 | */
106 | public function getMatches()
107 | {
108 | preg_match($this->getPattern(), $this->name, $matches);
109 |
110 | return $matches;
111 | }
112 |
113 | /**
114 | * Get name pattern.
115 | *
116 | * @return string
117 | */
118 | public function getPattern()
119 | {
120 | switch ($action = $this->getAction()) {
121 | case 'add':
122 | case 'append':
123 | case 'update':
124 | case 'insert':
125 | return "/{$action}_(.*)_to_(.*)_table/";
126 | break;
127 |
128 | case 'delete':
129 | case 'remove':
130 | case 'alter':
131 | return "/{$action}_(.*)_from_(.*)_table/";
132 | break;
133 | default:
134 | return "/{$action}_(.*)_table/";
135 | break;
136 | }
137 | }
138 |
139 | /**
140 | * Get schema type or action.
141 | *
142 | * @return string
143 | */
144 | public function getAction()
145 | {
146 | return head($this->data);
147 | }
148 |
149 | /**
150 | * Get the array data.
151 | *
152 | * @return array
153 | */
154 | public function getData()
155 | {
156 | return $this->data;
157 | }
158 |
159 | /**
160 | * Determine whether the given type is same with the current schema action or type.
161 | *
162 | * @param $type
163 | *
164 | * @return bool
165 | */
166 | public function is($type)
167 | {
168 | return $type == $this->getAction();
169 | }
170 |
171 | /**
172 | * Determine whether the current schema action is a adding action.
173 | *
174 | * @return bool
175 | */
176 | public function isAdd()
177 | {
178 | return in_array($this->getAction(), $this->actions['add']);
179 | }
180 |
181 | /**
182 | * Determine whether the current schema action is a deleting action.
183 | *
184 | * @return bool
185 | */
186 | public function isDelete()
187 | {
188 | return in_array($this->getAction(), $this->actions['delete']);
189 | }
190 |
191 | /**
192 | * Determine whether the current schema action is a creating action.
193 | *
194 | * @return bool
195 | */
196 | public function isCreate()
197 | {
198 | return in_array($this->getAction(), $this->actions['create']);
199 | }
200 |
201 | /**
202 | * Determine whether the current schema action is a dropping action.
203 | *
204 | * @return bool
205 | */
206 | public function isDrop()
207 | {
208 | return in_array($this->getAction(), $this->actions['drop']);
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Migrations/RulesParser.php:
--------------------------------------------------------------------------------
1 | rules = $rules;
29 | }
30 |
31 | /**
32 | * Convert string migration to array.
33 | *
34 | * @return array
35 | */
36 | public function toArray()
37 | {
38 | return $this->parse($this->rules);
39 | }
40 |
41 | /**
42 | * Parse a string to array of formatted rules.
43 | *
44 | * @param string $rules
45 | *
46 | * @return array
47 | */
48 | public function parse($rules)
49 | {
50 | $this->rules = $rules;
51 | $parsed = [];
52 | foreach ($this->getRules() as $rulesArray) {
53 | $column = $this->getColumn($rulesArray);
54 | $attributes = $this->getAttributes($column, $rulesArray);
55 | $parsed[$column] = $attributes;
56 | }
57 |
58 | return $parsed;
59 | }
60 |
61 | /**
62 | * Get array of rules.
63 | *
64 | * @return array
65 | */
66 | public function getRules()
67 | {
68 | if (is_null($this->rules)) {
69 | return [];
70 | }
71 |
72 | return explode(',', str_replace(' ', '', $this->rules));
73 | }
74 |
75 | /**
76 | * Get column name from rules.
77 | *
78 | * @param string $rules
79 | *
80 | * @return string
81 | */
82 | public function getColumn($rules)
83 | {
84 | return array_first(explode('=>', $rules), function ($key, $value) {
85 | return $value;
86 | });
87 | }
88 |
89 |
90 | /**
91 | * Get column attributes.
92 | *
93 | * @param string $column
94 | * @param string $rules
95 | *
96 | * @return array
97 | */
98 | public function getAttributes($column, $rules)
99 | {
100 |
101 | return str_replace($column . '=>', '', $rules);
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Migrations/SchemaParser.php:
--------------------------------------------------------------------------------
1 | 'rememberToken()',
19 | 'soft_delete' => 'softDeletes()',
20 | ];
21 | /**
22 | * The migration schema.
23 | *
24 | * @var string
25 | */
26 | protected $schema;
27 |
28 | /**
29 | * Create new instance.
30 | *
31 | * @param string|null $schema
32 | */
33 | public function __construct($schema = null)
34 | {
35 | $this->schema = $schema;
36 | }
37 |
38 | /**
39 | * Render up migration fields.
40 | *
41 | * @return string
42 | */
43 | public function up()
44 | {
45 | return $this->render();
46 | }
47 |
48 | /**
49 | * Render the migration to formatted script.
50 | *
51 | * @return string
52 | */
53 | public function render()
54 | {
55 | $results = '';
56 | foreach ($this->toArray() as $column => $attributes) {
57 | $results .= $this->createField($column, $attributes);
58 | }
59 |
60 | return $results;
61 | }
62 |
63 | /**
64 | * Convert string migration to array.
65 | *
66 | * @return array
67 | */
68 | public function toArray()
69 | {
70 | return $this->parse($this->schema);
71 | }
72 |
73 | /**
74 | * Parse a string to array of formatted schema.
75 | *
76 | * @param string $schema
77 | *
78 | * @return array
79 | */
80 | public function parse($schema)
81 | {
82 | $this->schema = $schema;
83 | $parsed = [];
84 | foreach ($this->getSchemas() as $schemaArray) {
85 | $column = $this->getColumn($schemaArray);
86 | $attributes = $this->getAttributes($column, $schemaArray);
87 | $parsed[$column] = $attributes;
88 | }
89 |
90 | return $parsed;
91 | }
92 |
93 | /**
94 | * Get array of schema.
95 | *
96 | * @return array
97 | */
98 | public function getSchemas()
99 | {
100 | if (is_null($this->schema)) {
101 | return [];
102 | }
103 |
104 | return explode(',', str_replace(' ', '', $this->schema));
105 | }
106 |
107 | /**
108 | * Get column name from schema.
109 | *
110 | * @param string $schema
111 | *
112 | * @return string
113 | */
114 | public function getColumn($schema)
115 | {
116 | return array_first(explode(':', $schema), function ($key, $value) {
117 | return $value;
118 | });
119 | }
120 |
121 | /**
122 | * Get column attributes.
123 | *
124 | * @param string $column
125 | * @param string $schema
126 | *
127 | * @return array
128 | */
129 | public function getAttributes($column, $schema)
130 | {
131 | $fields = str_replace($column . ':', '', $schema);
132 |
133 | return $this->hasCustomAttribute($column) ? $this->getCustomAttribute($column) : explode(':', $fields);
134 | }
135 |
136 | /**
137 | * Determinte whether the given column is exist in customAttributes array.
138 | *
139 | * @param string $column
140 | *
141 | * @return boolean
142 | */
143 | public function hasCustomAttribute($column)
144 | {
145 | return array_key_exists($column, $this->customAttributes);
146 | }
147 |
148 | /**
149 | * Get custom attributes value.
150 | *
151 | * @param string $column
152 | *
153 | * @return array
154 | */
155 | public function getCustomAttribute($column)
156 | {
157 | return (array)$this->customAttributes[$column];
158 | }
159 |
160 | /**
161 | * Create field.
162 | *
163 | * @param string $column
164 | * @param array $attributes
165 | *
166 | * @return string
167 | */
168 | public function createField($column, $attributes, $type = 'add')
169 | {
170 | $results = "\t\t\t" . '$table';
171 | foreach ($attributes as $key => $field) {
172 | $results .= $this->{"{$type}Column"}($key, $field, $column);
173 | }
174 |
175 | return $results .= ';' . PHP_EOL;
176 | }
177 |
178 | /**
179 | * Render down migration fields.
180 | *
181 | * @return string
182 | */
183 | public function down()
184 | {
185 | $results = '';
186 | foreach ($this->toArray() as $column => $attributes) {
187 | $results .= $this->createField($column, $attributes, 'remove');
188 | }
189 |
190 | return $results;
191 | }
192 |
193 | /**
194 | * Format field to script.
195 | *
196 | * @param int $key
197 | * @param string $field
198 | * @param string $column
199 | *
200 | * @return string
201 | */
202 | protected function addColumn($key, $field, $column)
203 | {
204 | if ($this->hasCustomAttribute($column)) {
205 | return '->' . $field;
206 | }
207 | if ($key == 0) {
208 | return '->' . $field . "('" . $column . "')";
209 | }
210 | if (str_contains($field, '(')) {
211 | return '->' . $field;
212 | }
213 |
214 | return '->' . $field . '()';
215 | }
216 |
217 | /**
218 | * Format field to script.
219 | *
220 | * @param int $key
221 | * @param string $field
222 | * @param string $column
223 | *
224 | * @return string
225 | */
226 | protected function removeColumn($key, $field, $column)
227 | {
228 | if ($this->hasCustomAttribute($column)) {
229 | return '->' . $field;
230 | }
231 |
232 | return '->dropColumn(' . "'" . $column . "')";
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/ModelGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
29 | }
30 |
31 | /**
32 | * Get generator path config node.
33 | *
34 | * @return string
35 | */
36 | public function getPathConfigNode()
37 | {
38 | return 'models';
39 | }
40 |
41 | /**
42 | * Get destination path for generated file.
43 | *
44 | * @return string
45 | */
46 | public function getPath()
47 | {
48 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . '.php';
49 | }
50 |
51 | /**
52 | * Get base path of destination file.
53 | *
54 | * @return string
55 | */
56 |
57 | public function getBasePath()
58 | {
59 | return config('repository.generator.basePath', app_path());
60 | }
61 |
62 | /**
63 | * Get array replacements.
64 | *
65 | * @return array
66 | */
67 | public function getReplacements()
68 | {
69 | return array_merge(parent::getReplacements(), [
70 | 'fillable' => $this->getFillable(),
71 | 'use_base_model' => 'use ' . $this->getRootNamespace() . '\BaseModel;',
72 | ]);
73 | }
74 |
75 | /**
76 | * Get the fillable attributes.
77 | *
78 | * @return string
79 | */
80 | public function getFillable()
81 | {
82 | if (!$this->fillable) {
83 | return '[]';
84 | }
85 | $results = '[' . PHP_EOL;
86 |
87 | foreach ($this->getSchemaParser()->toArray() as $column => $value) {
88 | $results .= "\t\t'{$column}'," . PHP_EOL;
89 | }
90 |
91 | return $results . "\t" . ']';
92 | }
93 |
94 | /**
95 | * Get schema parser.
96 | *
97 | * @return SchemaParser
98 | */
99 | public function getSchemaParser()
100 | {
101 | return new SchemaParser($this->fillable);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/PresenterGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
26 | }
27 |
28 | /**
29 | * Get generator path config node.
30 | *
31 | * @return string
32 | */
33 | public function getPathConfigNode()
34 | {
35 | return 'presenters';
36 | }
37 |
38 | /**
39 | * Get array replacements.
40 | *
41 | * @return array
42 | */
43 | public function getReplacements()
44 | {
45 | $transformerGenerator = new TransformerGenerator([
46 | 'name' => $this->name
47 | ]);
48 | $transformer = $transformerGenerator->getRootNamespace() . '\\' . $transformerGenerator->getName() . 'Transformer';
49 | $transformer = str_replace([
50 | "\\",
51 | '/'
52 | ], '\\', $transformer);
53 | echo $transformer;
54 |
55 | return array_merge(parent::getReplacements(), [
56 | 'transformer' => $transformer
57 | ]);
58 | }
59 |
60 | /**
61 | * Get destination path for generated file.
62 | *
63 | * @return string
64 | */
65 | public function getPath()
66 | {
67 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . 'Presenter.php';
68 | }
69 |
70 | /**
71 | * Get base path of destination file.
72 | *
73 | * @return string
74 | */
75 | public function getBasePath()
76 | {
77 | return config('repository.generator.basePath', app_path());
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/RepositoryEloquentGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
28 | }
29 |
30 | /**
31 | * Get generator path config node.
32 | *
33 | * @return string
34 | */
35 | public function getPathConfigNode()
36 | {
37 | return 'repositories';
38 | }
39 |
40 | /**
41 | * Get destination path for generated file.
42 | *
43 | * @return string
44 | */
45 | public function getPath()
46 | {
47 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . 'RepositoryEloquent.php';
48 | }
49 |
50 | /**
51 | * Get base path of destination file.
52 | *
53 | * @return string
54 | */
55 | public function getBasePath()
56 | {
57 | return config('repository.generator.basePath', app_path());
58 | }
59 |
60 | /**
61 | * Get array replacements.
62 | *
63 | * @return array
64 | */
65 | public function getReplacements()
66 | {
67 | $repository = parent::getRootNamespace() . parent::getConfigGeneratorClassPath('interfaces') . '\\' . $this->name . 'Repository;';
68 | $repository = str_replace([
69 | "\\",
70 | '/'
71 | ], '\\', $repository);
72 |
73 | return array_merge(parent::getReplacements(), [
74 | 'fillable' => $this->getFillable(),
75 | 'use_validator' => $this->getValidatorUse(),
76 | 'validator' => $this->getValidatorMethod(),
77 | 'use_presenter' => $this->getPresenterUse(),
78 | 'root_namespace' => parent::getRootNamespace(),
79 | 'presenter' => $this->getPresenterMethod(),
80 | 'repository' => $repository,
81 | 'model' => isset($this->options['model']) ? $this->options['model'] : ''
82 | ]);
83 | }
84 |
85 | /**
86 | * Get the fillable attributes.
87 | *
88 | * @return string
89 | */
90 | public function getFillable()
91 | {
92 | if (!$this->fillable) {
93 | return '[]';
94 | }
95 | $results = '[' . PHP_EOL;
96 |
97 | foreach ($this->getSchemaParser()->toArray() as $column => $value) {
98 | $results .= "\t\t'{$column}'," . PHP_EOL;
99 | }
100 |
101 | return $results . "\t" . ']';
102 | }
103 |
104 | /**
105 | * Get schema parser.
106 | *
107 | * @return SchemaParser
108 | */
109 | public function getSchemaParser()
110 | {
111 | return new SchemaParser($this->fillable);
112 | }
113 |
114 | public function getValidatorUse()
115 | {
116 | $validator = $this->getValidator();
117 |
118 | return "use {$validator};";
119 | }
120 |
121 |
122 | public function getValidator()
123 | {
124 | $validatorGenerator = new ValidatorGenerator([
125 | 'name' => $this->name,
126 | 'rules' => $this->rules,
127 | 'force' => $this->force,
128 | ]);
129 |
130 | $validator = $validatorGenerator->getRootNamespace() . '\\' . $validatorGenerator->getName();
131 |
132 | return str_replace([
133 | "\\",
134 | '/'
135 | ], '\\', $validator) . 'Validator';
136 |
137 | }
138 |
139 |
140 | public function getValidatorMethod()
141 | {
142 | if ($this->validator != 'yes') {
143 | return '';
144 | }
145 |
146 | $class = $this->getClass();
147 |
148 | return '/**' . PHP_EOL . ' * Specify Validator class name' . PHP_EOL . ' *' . PHP_EOL . ' * @return mixed' . PHP_EOL . ' */' . PHP_EOL . ' public function validator()' . PHP_EOL . ' {' . PHP_EOL . PHP_EOL . ' return ' . $class . 'Validator::class;' . PHP_EOL . ' }' . PHP_EOL;
149 |
150 | }
151 |
152 | public function getPresenterUse()
153 | {
154 | $presenter = $this->getPresenter();
155 |
156 | return "use {$presenter};";
157 | }
158 |
159 | public function getPresenter()
160 | {
161 | $presenterGenerator = new PresenterGenerator([
162 | 'name' => $this->name,
163 | 'rules' => $this->rules,
164 | 'force' => $this->force,
165 | ]);
166 |
167 | $presenter = $presenterGenerator->getRootNamespace() . '\\' . $presenterGenerator->getName();
168 |
169 | return str_replace([
170 | "\\",
171 | '/'
172 | ], '\\', $presenter) . 'Presenter';
173 |
174 | }
175 |
176 | public function getPresenterMethod()
177 | {
178 | if ($this->presenter != 'yes') {
179 | return '';
180 | }
181 |
182 | $class = $this->getClass();
183 |
184 | return '/**' . PHP_EOL . ' * Specify Presenter class name' . PHP_EOL . ' *' . PHP_EOL . ' * @return mixed' . PHP_EOL . ' */' . PHP_EOL . ' public function presenter()' . PHP_EOL . ' {' . PHP_EOL . PHP_EOL . ' return ' . $class . 'Presenter::class;' . PHP_EOL . ' }' . PHP_EOL;
185 |
186 | }
187 |
188 | }
189 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/RepositoryInterfaceGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
29 | }
30 |
31 | /**
32 | * Get generator path config node.
33 | *
34 | * @return string
35 | */
36 | public function getPathConfigNode()
37 | {
38 | return 'interfaces';
39 | }
40 |
41 | /**
42 | * Get destination path for generated file.
43 | *
44 | * @return string
45 | */
46 | public function getPath()
47 | {
48 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . 'Repository.php';
49 | }
50 |
51 | /**
52 | * Get base path of destination file.
53 | *
54 | * @return string
55 | */
56 | public function getBasePath()
57 | {
58 | return config('repository.generator.basePath', app_path());
59 | }
60 |
61 | /**
62 | * Get array replacements.
63 | *
64 | * @return array
65 | */
66 | public function getReplacements()
67 | {
68 | return array_merge(parent::getReplacements(), [
69 | 'fillable' => $this->getFillable()
70 | ]);
71 | }
72 |
73 | /**
74 | * Get the fillable attributes.
75 | *
76 | * @return string
77 | */
78 | public function getFillable()
79 | {
80 | if (!$this->fillable) {
81 | return '[]';
82 | }
83 | $results = '[' . PHP_EOL;
84 |
85 | foreach ($this->getSchemaParser()->toArray() as $column => $value) {
86 | $results .= "\t\t'{$column}'," . PHP_EOL;
87 | }
88 |
89 | return $results . "\t" . ']';
90 | }
91 |
92 | /**
93 | * Get schema parser.
94 | *
95 | * @return SchemaParser
96 | */
97 | public function getSchemaParser()
98 | {
99 | return new SchemaParser($this->fillable);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stub.php:
--------------------------------------------------------------------------------
1 | path = $path;
39 | $this->replaces = $replaces;
40 | }
41 |
42 | /**
43 | * Create new self instance.
44 | *
45 | * @param string $path
46 | * @param array $replaces
47 | *
48 | * @return self
49 | */
50 | public static function create($path, array $replaces = [])
51 | {
52 | return new static($path, $replaces);
53 | }
54 |
55 | /**
56 | * Set base path.
57 | *
58 | * @param string $path
59 | *
60 | * @return void
61 | */
62 | public static function setBasePath($path)
63 | {
64 | static::$basePath = $path;
65 | }
66 |
67 | /**
68 | * Set replacements array.
69 | *
70 | * @param array $replaces
71 | *
72 | * @return $this
73 | */
74 | public function replace(array $replaces = [])
75 | {
76 | $this->replaces = $replaces;
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * Get replacements.
83 | *
84 | * @return array
85 | */
86 | public function getReplaces()
87 | {
88 | return $this->replaces;
89 | }
90 |
91 | /**
92 | * Handle magic method __toString.
93 | *
94 | * @return string
95 | */
96 | public function __toString()
97 | {
98 | return $this->render();
99 | }
100 |
101 | /**
102 | * Get stub contents.
103 | *
104 | * @return string
105 | */
106 | public function render()
107 | {
108 | return $this->getContents();
109 | }
110 |
111 | /**
112 | * Get stub contents.
113 | *
114 | * @return mixed|string
115 | */
116 | public function getContents()
117 | {
118 | $contents = file_get_contents($this->getPath());
119 | foreach ($this->replaces as $search => $replace) {
120 | $contents = str_replace('$' . strtoupper($search) . '$', $replace, $contents);
121 | }
122 |
123 | return $contents;
124 | }
125 |
126 | /**
127 | * Get stub path.
128 | *
129 | * @return string
130 | */
131 | public function getPath()
132 | {
133 | return static::$basePath . $this->path;
134 | }
135 |
136 | /**
137 | * Set stub path.
138 | *
139 | * @param string $path
140 | *
141 | * @return self
142 | */
143 | public function setPath($path)
144 | {
145 | $this->path = $path;
146 |
147 | return $this;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/bindings/bindings.stub:
--------------------------------------------------------------------------------
1 |
2 | $this->app->bind($REPOSITORY$, $ELOQUENT$);
3 | $PLACEHOLDER$
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/controller/controller.stub:
--------------------------------------------------------------------------------
1 | repository = $repository;
31 | $this->validator = $validator;
32 | }
33 |
34 | /**
35 | * Display a listing of the resource.
36 | *
37 | * @param Request $request
38 | * @return \Illuminate\Http\Response
39 | */
40 | public function index(Request $request)
41 | {
42 | return $this->repository->paginate();
43 | }
44 |
45 | /**
46 | * Display all resources.
47 | *
48 | * @param Request $request
49 | * @return \Illuminate\Http\Response
50 | */
51 | public function all(Request $request)
52 | {
53 | return $this->repository->all();
54 | }
55 |
56 | /**
57 | * Store a newly created resource in storage.
58 | *
59 | * @param $CLASS$CreateRequest $request
60 | *
61 | * @return \Illuminate\Http\Response
62 | */
63 | public function store($CLASS$CreateRequest $request)
64 | {
65 |
66 | $data = $request->all();
67 |
68 | $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_CREATE);
69 |
70 | $$SINGULAR$ = $this->repository->create($data);
71 |
72 | // throw exception if store failed
73 | // throw new StoreResourceFailedException('Failed to store.');
74 |
75 | // A. return 201 created
76 | // return $this->response->created(null);
77 |
78 | // B. return data
79 | return $$SINGULAR$;
80 |
81 | }
82 |
83 |
84 | /**
85 | * Display the specified resource.
86 | *
87 | * @param int $id
88 | *
89 | * @return \Illuminate\Http\Response
90 | */
91 | public function show($id)
92 | {
93 | return $this->repository->find($id);
94 | }
95 |
96 | /**
97 | * Update the specified resource in storage.
98 | *
99 | * @param $CLASS$UpdateRequest $request
100 | * @param string $id
101 | *
102 | * @return Response
103 | */
104 | public function update($CLASS$UpdateRequest $request, $id)
105 | {
106 |
107 | $data = $request->all();
108 |
109 | $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_UPDATE);
110 |
111 | $$SINGULAR$ = $this->repository->update($data, $id);
112 |
113 | // throw exception if update failed
114 | // throw new UpdateResourceFailedException('Failed to update.');
115 |
116 | // Updated, return 204 No Content
117 | return $this->response->noContent();
118 |
119 | }
120 |
121 |
122 | /**
123 | * Remove the specified resource from storage.
124 | *
125 | * @param int $id
126 | *
127 | * @return \Illuminate\Http\Response
128 | */
129 | public function destroy($id)
130 | {
131 | $deleted = $this->repository->delete($id);
132 |
133 | if ($deleted) {
134 | // Deleted, return 204 No Content
135 | return $this->response->noContent();
136 | } else {
137 | // Failed, throw exception
138 | throw new DeleteResourceFailedException('Failed to delete.');
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/criteria/criteria.stub:
--------------------------------------------------------------------------------
1 | increments('$TABLE_SINGULAR$_id');
18 | $table->unsignedInteger('user_id')->index();
19 |
20 | // Adding more table related fields here...
21 | $FIELDS$
22 |
23 | $table->unsignedInteger('created_by')->nullable();
24 | $table->timestamp('created_at')->nullable();
25 | $table->ipAddress('created_ip')->nullable();
26 | $table->unsignedInteger('updated_by')->nullable();
27 | $table->timestamp('updated_at')->nullable();
28 | $table->ipAddress('updated_ip')->nullable();
29 | });
30 | }
31 |
32 | /**
33 | * Reverse the migrations.
34 | *
35 | * @return void
36 | */
37 | public function down()
38 | {
39 | Schema::drop('$TABLE$');
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/model.stub:
--------------------------------------------------------------------------------
1 | pushCriteria(app(RequestCriteria::class));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/repository/interface.stub:
--------------------------------------------------------------------------------
1 | call("OthersTableSeeder");
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/transformer/transformer.stub:
--------------------------------------------------------------------------------
1 | (int) $model->id,
24 |
25 | /* place your other model properties here */
26 |
27 | 'created_at' => (string) $model->created_at,
28 | 'updated_at' => (string) $model->updated_at
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/Stubs/validator/validator.stub:
--------------------------------------------------------------------------------
1 | $RULES$,
13 | ValidatorInterface::RULE_UPDATE => $RULES$,
14 | ];
15 | }
16 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/TransformerGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
26 | }
27 |
28 | /**
29 | * Get generator path config node.
30 | *
31 | * @return string
32 | */
33 | public function getPathConfigNode()
34 | {
35 | return 'transformers';
36 | }
37 |
38 | /**
39 | * Get destination path for generated file.
40 | *
41 | * @return string
42 | */
43 | public function getPath()
44 | {
45 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . 'Transformer.php';
46 | }
47 |
48 | /**
49 | * Get base path of destination file.
50 | *
51 | * @return string
52 | */
53 | public function getBasePath()
54 | {
55 | return config('repository.generator.basePath', app_path());
56 | }
57 |
58 | /**
59 | * Get array replacements.
60 | *
61 | * @return array
62 | */
63 | public function getReplacements()
64 | {
65 | $modelGenerator = new ModelGenerator([
66 | 'name' => $this->name
67 | ]);
68 | $model = $modelGenerator->getRootNamespace() . '\\' . $modelGenerator->getName();
69 | $model = str_replace([
70 | "\\",
71 | '/'
72 | ], '\\', $model);
73 |
74 | return array_merge(parent::getReplacements(), [
75 | 'model' => $model
76 | ]);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Generators/ValidatorGenerator.php:
--------------------------------------------------------------------------------
1 | getPathConfigNode());
29 | }
30 |
31 | /**
32 | * Get generator path config node.
33 | *
34 | * @return string
35 | */
36 | public function getPathConfigNode()
37 | {
38 | return 'validators';
39 | }
40 |
41 | /**
42 | * Get destination path for generated file.
43 | *
44 | * @return string
45 | */
46 | public function getPath()
47 | {
48 | return $this->getBasePath() . '/' . parent::getConfigGeneratorClassPath($this->getPathConfigNode(), true) . '/' . $this->getName() . 'Validator.php';
49 | }
50 |
51 | /**
52 | * Get base path of destination file.
53 | *
54 | * @return string
55 | */
56 | public function getBasePath()
57 | {
58 | return config('repository.generator.basePath', app_path());
59 | }
60 |
61 | /**
62 | * Get array replacements.
63 | *
64 | * @return array
65 | */
66 | public function getReplacements()
67 | {
68 |
69 | return array_merge(parent::getReplacements(), [
70 | 'rules' => $this->getRules(),
71 | ]);
72 | }
73 |
74 | /**
75 | * Get the rules.
76 | *
77 | * @return string
78 | */
79 | public function getRules()
80 | {
81 | if (!$this->rules) {
82 | return '[]';
83 | }
84 | $results = '[' . PHP_EOL;
85 |
86 | foreach ($this->getSchemaParser()->toArray() as $column => $value) {
87 | $results .= "\t\t'{$column}'\t=>'\t{$value}'," . PHP_EOL;
88 | }
89 |
90 | return $results . "\t" . ']';
91 | }
92 |
93 | /**
94 | * Get schema parser.
95 | *
96 | * @return SchemaParser
97 | */
98 | public function getSchemaParser()
99 | {
100 | return new RulesParser($this->rules);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Someline/Repository/Providers/RepositoryServiceProvider.php:
--------------------------------------------------------------------------------
1 | mergeConfigFrom(base_path('vendor/prettus/l5-repository/src/resources/config/repository.php'), 'repository');
28 |
29 | $this->loadTranslationsFrom(base_path('vendor/prettus/l5-repository/src/resources/lang'), 'repository');
30 | }
31 |
32 |
33 | /**
34 | * Register the service provider.
35 | *
36 | * @return void
37 | */
38 | public function register()
39 | {
40 | $this->commands('Someline\Repository\Generators\Commands\RepositoryCommand');
41 | $this->commands('Someline\Repository\Generators\Commands\TransformerCommand');
42 | $this->commands('Someline\Repository\Generators\Commands\PresenterCommand');
43 | $this->commands('Someline\Repository\Generators\Commands\EntityCommand');
44 | $this->commands('Someline\Repository\Generators\Commands\ValidatorCommand');
45 | $this->commands('Someline\Repository\Generators\Commands\ControllerCommand');
46 | $this->commands('Someline\Repository\Generators\Commands\BindingsCommand');
47 | $this->commands('Someline\Repository\Generators\Commands\CriteriaCommand');
48 | }
49 |
50 |
51 | /**
52 | * Get the services provided by the provider.
53 | *
54 | * @return array
55 | */
56 | public function provides()
57 | {
58 | return [];
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Someline/Support/Controllers/LocaleController.php:
--------------------------------------------------------------------------------
1 | make($content);
24 | $response->header('Content-Type', 'application/javascript');
25 | $response->setPublic()
26 | ->setMaxAge(604800)
27 | ->setExpires(Carbon::now()->addDay(7));
28 | return $response;
29 | }
30 |
31 | /**
32 | * @param Request $request
33 | * @param $locale
34 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
35 | */
36 | public function getSwitchLocale(Request $request, $locale)
37 | {
38 | // check if supported
39 | $supportedLanguagesKeys = \LaravelLocalization::getSupportedLanguagesKeys();
40 | if (!in_array($locale, $supportedLanguagesKeys)) {
41 | abort(404);
42 | }
43 |
44 | // store in session
45 | session(['someline-locale' => $locale]);
46 |
47 | // check if has redirect url
48 | $redirect_url = '/';
49 | if ($request->has('redirect_url')) {
50 | $redirect_url = $request->get('redirect_url');
51 | }
52 | return redirect($redirect_url);
53 | }
54 |
55 | }
--------------------------------------------------------------------------------
/src/Someline/Support/Middleware/LocaleMiddleware.php:
--------------------------------------------------------------------------------
1 | get('lang');
38 | if (!empty($lang)) {
39 | // if supported
40 | if (is_array($supportedLocales) && isset($supportedLocales[$lang])) {
41 | $locale = $lang;
42 | }
43 | }
44 |
45 | // set locale
46 | LaravelLocalization::setLocale($locale);
47 |
48 | // set carbon locale
49 | Carbon::setLocale($locale);
50 |
51 | return $next($request);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/Someline/Transformers/BasicTransformer.php:
--------------------------------------------------------------------------------
1 |