Skip to content

Commit 4c4b51a

Browse files
committed
Re-initialize
0 parents  commit 4c4b51a

31 files changed

+34228
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/composer.lock
2+
/composer.phar
3+
/phpunit.xml
4+
/.phpunit.result.cache
5+
/phpunit.phar
6+
/config/Migrations/schema-dump-default.lock
7+
/vendor/
8+
/.idea/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 - present SilvarCode / SilvarCode.com (https://silvarcode.com)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# SilvarCode/Autocomplete cakephp plugin
2+
3+
## Installation
4+
5+
You can install this plugin into your CakePHP application using [composer](https://getcomposer.org).
6+
7+
The recommended way to install composer packages is:
8+
9+
```
10+
composer require silvarcode/autocomplete
11+
```
12+
13+
## Instructions
14+
15+
Instructions on how to use the plugin can be found on the website.
16+
Check the blog section of the website for a post on how to install and use the cakephp powered autocomplete plugin.

composer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "silvarcode/autocomplete",
3+
"description": "SilvarCode/Autocomplete plugin for CakePHP",
4+
"type": "cakephp-plugin",
5+
"license": "MIT",
6+
"authors": [],
7+
"homepage": "https://github.com/SilvarCode/Autocomplete",
8+
"keywords": [
9+
"cakephp",
10+
"autocomplete",
11+
"cakephp-autocomplete-plugin"
12+
],
13+
"require": {
14+
"php": ">=8",
15+
"cakephp/cakephp": ">=4.4 <6.0",
16+
"cakephp/bake": "^3.2"
17+
},
18+
"autoload": {
19+
"psr-4": {
20+
"SilvarCode\\Autocomplete\\": "src/"
21+
}
22+
}
23+
}

src/Command/CopyAssetsCommand.php

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* ***********************************
6+
* || CopyAssetsCommand ||
7+
* ***********************************
8+
*
9+
* @copyright 2022 SilvarCode / SilvarCode.com
10+
* All rights reserved.
11+
* @link https://silvarcode.com
12+
* @since 1.0.0
13+
* @license MIT License - see LICENSE.txt for more details.
14+
* Redistributions of files must retain the above notice.
15+
* https://opensource.org/licenses/mit-license.php MIT License
16+
*/
17+
namespace SilvarCode\Autocomplete\Command;
18+
19+
use Bake\Command\BakeCommand;
20+
use Cake\Console\Arguments;
21+
use Cake\Console\ConsoleIo;
22+
use Cake\Console\ConsoleOptionParser;
23+
use Cake\Core\Plugin;
24+
use RecursiveDirectoryIterator;
25+
use RecursiveIteratorIterator;
26+
27+
/**
28+
* CopyAssets command.
29+
*/
30+
class CopyAssetsCommand extends BakeCommand
31+
{
32+
/**
33+
* @return string
34+
*/
35+
public static function defaultName(): string
36+
{
37+
return 'bake copy-autocomplete-assets';
38+
}
39+
40+
/**
41+
* Hook method for defining this command's option parser.
42+
*
43+
* @see https://book.cakephp.org/4/en/console-commands/commands.html#defining-arguments-and-options
44+
* @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined
45+
* @return \Cake\Console\ConsoleOptionParser The built parser.
46+
*/
47+
public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
48+
{
49+
$DS = DIRECTORY_SEPARATOR;
50+
$parser = parent::buildOptionParser($parser);
51+
$webroot = rtrim(WWW_ROOT, $DS);
52+
53+
$parser->setDescription(
54+
'The sole purpose of this command is to <info>copy</info> ' .
55+
"the assets from the plugin's webroot into $webroot{$DS}autocomplete$DS"
56+
)->addOption('confirm', [
57+
'help' => 'Please confirm you would like to copy webroot assets',
58+
'required' => true,
59+
'choices' => ['yes', 'no'],
60+
]);
61+
62+
return $parser;
63+
}
64+
65+
/**
66+
* Implement this method with your command's logic.
67+
*
68+
* @param \Cake\Console\Arguments $args The command arguments.
69+
* @param \Cake\Console\ConsoleIo $io The console io
70+
* @return null|void|int The exit code or null for success
71+
*/
72+
public function execute(Arguments $args, ConsoleIo $io)
73+
{
74+
if (in_array(strtolower($args->getOption('confirm')), ['no', 'n'])) {
75+
return 1;
76+
}
77+
78+
$source = Plugin::path('SilvarCode/Autocomplete');
79+
$source = rtrim($source, DS) . DS . 'webroot';
80+
$destination = WWW_ROOT . 'autocomplete' . DIRECTORY_SEPARATOR;
81+
82+
if (!is_dir($destination)) {
83+
if (!mkdir($destination, 0755, true)) {
84+
$io->err('Could not create destination directory: ' . $destination);
85+
return 1;
86+
}
87+
}
88+
89+
$files = $this->getFiles($source);
90+
foreach ($files as $file) {
91+
$target = $destination . basename($file);
92+
if (!copy($file, $target)) {
93+
$io->err('Failed to copy file: ' . $file);
94+
return 1;
95+
}
96+
}
97+
98+
$io->out('Assets copied to directory: ' . $destination);
99+
100+
return null;
101+
}
102+
103+
/**
104+
* Get all files from the source directory and its subdirectories.
105+
*
106+
* @param string $dir The directory path
107+
* @return array List of file paths
108+
*/
109+
private function getFiles(string $dir): array
110+
{
111+
$files = [];
112+
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
113+
foreach ($iterator as $fileInfo) {
114+
if ($fileInfo->isFile()) {
115+
$files[] = $fileInfo->getRealPath();
116+
}
117+
}
118+
return $files;
119+
}
120+
}

src/Controller/AutocompleteTrait.php

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* ***********************************
6+
* || AutocompleteTrait ||
7+
* ***********************************
8+
*
9+
* @copyright 2022 SilvarCode / SilvarCode.com
10+
* All rights reserved.
11+
* @link https://silvarcode.com
12+
* @since 1.0.0
13+
* @license MIT License - see LICENSE.txt for more details.
14+
* Redistributions of files must retain the above notice.
15+
* https://opensource.org/licenses/mit-license.php MIT License
16+
*/
17+
namespace SilvarCode\Autocomplete\Controller;
18+
19+
use Cake\Core\Configure;
20+
use Cake\Http\Response;
21+
22+
trait AutocompleteTrait
23+
{
24+
/**
25+
* @property $autocompleteTable
26+
*/
27+
protected ?string $autocompleteTable = null;
28+
29+
/**
30+
* @property array $autocompleteSelectFields
31+
*/
32+
protected array $autocompleteSelectFields = [];
33+
34+
/**
35+
* @property array $autocompleteContain
36+
*/
37+
protected array $autocompleteContain = [];
38+
39+
/**
40+
* @param string $table
41+
* @return void
42+
*/
43+
protected function setAutocompleteTable(string $table): void
44+
{
45+
$this->autocompleteTable = $table;
46+
}
47+
48+
/**
49+
* @return string
50+
*/
51+
protected function getAutocompleteTable(): string
52+
{
53+
if (empty($this->autocompleteTable) && isset($this->defaultTable)) {
54+
$this->setAutocompleteTable($this->defaultTable);
55+
}
56+
57+
return $this->autocompleteTable;
58+
}
59+
60+
/**
61+
* @param array $fields
62+
* @return void
63+
*/
64+
protected function setAutocompleteSelectFields(array $fields = []): void
65+
{
66+
$this->autocompleteSelectFields = $fields;
67+
}
68+
69+
/**
70+
* @return array
71+
*/
72+
protected function getAutocompleteSelectFields(): array
73+
{
74+
return $this->autocompleteSelectFields;
75+
}
76+
77+
/**
78+
* @param array $autocompleteContain
79+
* @return void
80+
*/
81+
protected function setAutocompleteContain(array $autocompleteContain = []): void
82+
{
83+
$this->autocompleteContain = $autocompleteContain;
84+
}
85+
86+
/**
87+
* @return array
88+
*/
89+
protected function getAutocompleteContain(): array
90+
{
91+
return $this->autocompleteContain;
92+
}
93+
94+
/**
95+
* @return void
96+
*/
97+
public function autocomplete(): void
98+
{
99+
$this->disableAutoRender();
100+
if ($this->request->is(['ajax'])) {
101+
$this->enableAutoRender();
102+
$this->viewBuilder()->setLayout('ajax');
103+
$component = 'Flash';
104+
if (empty($this->components()->has($component))) {
105+
$this->loadComponent($component);
106+
}
107+
108+
$term = 'term';
109+
$term = (string)$this->request->getData(
110+
$term,
111+
$this->request->getQuery(
112+
$term
113+
)
114+
);
115+
116+
$records = [];
117+
$displayField = null;
118+
if ($this->request->getAttribute('isAjax') || (Configure::read('debug'))) {
119+
$this->enableAutoRender();
120+
$table = $this->fetchTable($this->getAutocompleteTable());
121+
$alias = $table->getAlias();
122+
$displayField = $table->getDisplayField();
123+
$select = $this->getAutocompleteSelectFields();
124+
$select = !empty($select) ? $select : array_unique([
125+
$table->aliasField(
126+
$table->getPrimaryKey()
127+
),
128+
$table->aliasField(
129+
$table->getDisplayField()
130+
),
131+
]);
132+
133+
if (method_exists($this, 'getAutocompleteConditions')) {
134+
$conditions = $this->getAutocompleteConditions();
135+
} else {
136+
$conditions = [
137+
"{$alias}.{$displayField} LIKE" => '%' . $term . '%',
138+
];
139+
140+
if ($table->hasField('active')) {
141+
$conditions["{$alias}.active"] = 1;
142+
} elseif ($table->hasField('published')) {
143+
$conditions["{$alias}.published"] = 1;
144+
}
145+
}
146+
147+
$records = $table->find()
148+
->select($select)
149+
->contain($this->getAutocompleteContain())
150+
->where($conditions)
151+
->order([$table->aliasField($displayField) => 'ASC'])
152+
->limit(10)
153+
->all();
154+
}
155+
156+
$this->set(compact('records', 'displayField'));
157+
$this->response = $this->response->withCache('-1 minute', '+5 minutes');
158+
$this->response = $this->response->withType('application/json');
159+
160+
try {
161+
$this->render();
162+
} catch (\Exception $e) {
163+
$viewBuilder = $this->viewBuilder();
164+
$viewBuilder->setLayout('ajax');
165+
$viewBuilder->setPlugin('SilvarCode/Autocomplete');
166+
$viewBuilder->setTemplate('autocomplete');
167+
$viewBuilder->setTemplatePath('element');
168+
$this->render();
169+
}
170+
}
171+
}
172+
}

0 commit comments

Comments
 (0)