Issues (19)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/SearchableTrait.php (3 issues)

Labels

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @link https://github.com/vuongxuongminh/yii2-searchable
4
 * @copyright Copyright (c) 2019 Vuong Xuong Minh
5
 * @license [New BSD License](http://www.opensource.org/licenses/bsd-license.php)
6
 */
7
8
namespace vxm\searchable;
9
10
use Yii;
11
12
use yii\db\ActiveQueryInterface;
13
use yii\db\Exception;
14
15
use vxm\searchable\expression\Condition;
16
use vxm\searchable\expression\ConditionBuilder;
17
use vxm\searchable\expression\OrderBy;
18
use vxm\searchable\expression\OrderByBuilder;
19
20
/**
21
 * Trait SearchableTrait support implementing full-text search for the active record classes.
22
 *
23
 * @author Vuong Minh <[email protected]>
24
 * @since 1.0.0
25
 */
26
trait SearchableTrait
27
{
28
29
    /**
30
     * @inheritDoc
31
     * @return \yii\db\Connection
32
     */
33
    abstract public static function getDb();
34
35
    /**
36
     * @inheritDoc
37
     * @return string
38
     */
39
    abstract public static function tableName();
40
41
    /**
42
     * @inheritDoc
43
     * @return mixed
44
     */
45
    abstract public static function primaryKey();
46
47
    /**
48
     * @inheritDoc
49
     * @return \yii\db\ActiveQuery|\yii\db\ActiveQueryInterface
50
     */
51
    abstract public static function find();
52
53
    /**
54
     * Get searchable support full-text search for this model class.
55
     *
56
     * @return object|Searchable
57
     * @throws \yii\base\InvalidConfigException
58
     */
59 12
    public static function getSearchable(): Searchable
60
    {
61 12
        return Yii::$app->get('searchable');
62
    }
63
64
    /**
65
     * Creating active query had been apply search ids condition by given query string.
66
     *
67
     * @param string $query to search data.
68
     * @param string $mode using for query search, [[\vxm\searchable\Searchable::BOOLEAN_SEARCH]] or [[\vxm\searchable\Searchable::FUZZY_SEARCH]].
69
     * If not set [[\vxm\searchable\Searchable::$defaultSearchMode]] will be use.
70
     * @param array $config of [[\vxm\searchable\TNTSearch]].
71
     * @return \yii\db\ActiveQuery|ActiveQueryInterface query instance.
72
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
73
     * @throws \yii\base\InvalidConfigException
74
     */
75 6
    public static function search(string $query, ?string $mode = null, array $config = []): ActiveQueryInterface
76
    {
77 6
        $ids = static::searchIds($query, $mode, $config);
78
        /** @var \yii\db\ActiveQuery $aq */
79 6
        $aq = static::find();
80
81 6
        if (empty($ids)) {
82
83 3
            $aq->andWhere('1 = 0');
84
        } else {
85
            /** @var \yii\db\Connection $db */
86 4
            $db = static::getDb();
87 4
            $db->setQueryBuilder([
88 4
                'expressionBuilders' => [
89
                    Condition::class => ConditionBuilder::class,
90
                    OrderBy::class => OrderByBuilder::class
91
                ]
92
            ]);
93
            $expressionConfig = [
94 4
                'query' => $aq,
95 4
                'ids' => $ids
96
            ];
97 4
            $condition = new Condition($expressionConfig);
98 4
            $orderBy = new OrderBy($expressionConfig);
99 4
            $aq->andWhere($condition);
100 4
            $aq->addOrderBy($orderBy);
101
        }
102
103 6
        return $aq;
104
    }
105
106
    /**
107
     * Search ids by given query string.
108
     *
109
     * @param string $query to search data.
110
     * @param string|null $mode using for query search, [[\vxm\searchable\Searchable::BOOLEAN_SEARCH]] or [[\vxm\searchable\Searchable::FUZZY_SEARCH]].
111
     * If not set [[\vxm\searchable\Searchable::$defaultSearchMode]] will be use.
112
     * @param array $config of [[\vxm\searchable\TNTSearch]].
113
     * @return array search key values of indexing data search.
114
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
115
     * @throws \yii\base\InvalidConfigException
116
     */
117 8
    public static function searchIds(string $query, ?string $mode = null, array $config = []): array
118
    {
119 8
        $profileToken = "Searching data via query: `{$query}`";
120 8
        Yii::beginProfile($profileToken);
121
122
        try {
123 8
            $result = static::getSearchable()->search(static::class, $query, $mode, $config);
124
125 8
            return $result['ids'];
126
        } finally {
127
128 8
            Yii::endProfile($profileToken);
129
        }
130
    }
131
132
    /**
133
     * Delete all instances of the model from the search index.
134
     *
135
     * @throws \yii\base\InvalidConfigException
136
     */
137 5
    public static function deleteAllFromSearch(): void
138
    {
139 5
        static::getSearchable()->deleteAllFromSearch(static::class);
140 5
    }
141
142
    /**
143
     * Enable search syncing for this model class.
144
     */
145 2
    public static function enableSearchSyncing(): void
146
    {
147 2
        SearchableBehavior::enableSyncingFor(static::class);
148 2
    }
149
150
    /**
151
     * Disable search syncing for this model class.
152
     */
153 2
    public static function disableSearchSyncing(): void
154
    {
155 2
        SearchableBehavior::disableSyncingFor(static::class);
156 2
    }
157
158
    /**
159
     * Temporarily disable search syncing for the given callback.
160
     *
161
     * @param callable $callback will be call without syncing mode.
162
     * @return mixed value of $callback.
163
     */
164 2
    public static function withoutSyncingToSearch($callback)
165
    {
166 2
        static::disableSearchSyncing();
167
168
        try {
169 2
            return $callback();
170
        } finally {
171 2
            static::enableSearchSyncing();
172
        }
173
    }
174
175
    /**
176
     * Make given model searchable.
177
     *
178
     * @param \yii\db\ActiveRecord|\yii\db\ActiveRecord[]|static|static[] $models add to searchable index data.
179
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
180
     * @throws \yii\base\InvalidConfigException
181
     */
182 10
    public static function makeSearchable($models): void
183
    {
184 10
        static::getSearchable()->queueMakeSearchable($models);
0 ignored issues
show
It seems like $models defined by parameter $models on line 182 can also be of type array<integer,object<vxm...hable\SearchableTrait>> or object<vxm\searchable\SearchableTrait>; however, vxm\searchable\Searchable::queueMakeSearchable() does only seem to accept object<yii\db\ActiveReco...searchable\Searchable>>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
185 10
    }
186
187
    /**
188
     * Delete given model searchable.
189
     *
190
     * @param \yii\db\ActiveRecord|\yii\db\ActiveRecord[]|static|static[] $models delete from searchable index data.
191
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
192
     * @throws \yii\base\InvalidConfigException
193
     */
194 3
    public static function deleteSearchable($models): void
195
    {
196 3
        static::getSearchable()->queueDeleteFromSearch($models);
0 ignored issues
show
It seems like $models defined by parameter $models on line 194 can also be of type array<integer,object<vxm...hable\SearchableTrait>> or object<vxm\searchable\SearchableTrait>; however, vxm\searchable\Searchable::queueDeleteFromSearch() does only seem to accept object<yii\db\ActiveReco...searchable\Searchable>>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
197 3
    }
198
199
    /**
200
     * Make all instances of the model searchable.
201
     *
202
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
203
     * @throws \yii\base\InvalidConfigException
204
     */
205 7
    public static function makeAllSearchable(): void
206
    {
207 7
        foreach (static::find()->orderBy(static::searchableKey())->batch() as $models) {
208 7
            static::makeSearchable($models);
209
        }
210 7
    }
211
212
    /**
213
     * Get the index name for the model.
214
     *
215
     * @return string the name of an index.
216
     */
217 12
    public static function searchableIndex(): string
218
    {
219 12
        return static::getDb()->quoteSql(static::tableName());
220
    }
221
222
    /**
223
     * Get the indexable data array for the model.
224
     *
225
     * @return array ['field' => 'value'] or ['field alias' => 'value'].
226
     */
227 10
    public function toSearchableArray(): array
228
    {
229 10
        return $this->toArray();
0 ignored issues
show
It seems like toArray() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
230
    }
231
232
    /**
233
     * Get searchable key by default primary key will be use.
234
     *
235
     * @return string key name.
236
     */
237 11
    public static function searchableKey(): string
238
    {
239 11
        return current(static::primaryKey());
240
    }
241
242
    /**
243
     * Determine if the model should be searchable.
244
     *
245
     * @return bool weather instance should be insert to searchable index data.
246
     */
247
    public function shouldBeSearchable(): bool
248
    {
249
        return true;
250
    }
251
252
    /**
253
     * Make the given model instance searchable.
254
     *
255
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
256
     * @throws \yii\base\InvalidConfigException
257
     */
258 4
    public function searchable(): void
259
    {
260 4
        static::makeSearchable($this);
261 4
    }
262
263
    /**
264
     * Remove the given model instance from the search index.
265
     *
266
     * @throws \TeamTNT\TNTSearch\Exceptions\IndexNotFoundException
267
     * @throws \yii\base\InvalidConfigException
268
     */
269 3
    public function unsearchable(): void
270
    {
271 3
        static::deleteSearchable($this);
272 3
    }
273
274
    /**
275
     * Get searchable key value by default the primary key will be use.
276
     *
277
     * @param bool $asArray weather return an array have a key is a searchable key and value is an value of key or only value.
278
     * @return string|int|string[]|int[] value of an searchable key.
279
     * @throws Exception
280
     */
281 11
    public function getSearchableKey(bool $asArray = false)
282
    {
283 11
        $key = static::searchableKey();
284
285 11
        if ($asArray) {
286
            return [$key => $this->$key];
287
        } else {
288 11
            return $this->$key;
289
        }
290
    }
291
292
}
293