-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSearch.php
More file actions
206 lines (190 loc) · 6.23 KB
/
Search.php
File metadata and controls
206 lines (190 loc) · 6.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php
/**
* Search Model
*
* @author Noriko Arai <arai@nii.ac.jp>
* @author Shohei Nakajima <nakajimashouhei@gmail.com>
* @link http://www.netcommons.org NetCommons Project
* @license http://www.netcommons.org/license.txt NetCommons License
* @copyright Copyright 2014, NetCommons Project
*/
App::uses('SearchesAppModel', 'Searches.Model');
App::uses('Topic', 'Topics.Model');
App::uses('SiteSettingUtil', 'SiteManager.Utility');
App::uses('SiteSetting', 'SiteManager.Model');
App::uses('NetCommonsTime', 'NetCommons.Utility');
/**
* Search Model
*
* @author Shohei Nakajima <nakajimashouhei@gmail.com>
* @package NetCommons\Searches\Model
*/
class Search extends Topic {
/**
* AND条件
*
* @var string
*/
const WHERE_TYPE_AND = 'and';
/**
* OR条件
*
* @var string
*/
const WHERE_TYPE_OR = 'or';
/**
* フレーズ条件
*
* @var string
*/
const WHERE_TYPE_PHRASE = 'phrase';
/**
* Custom database table name, or null/false if no table association is desired.
*
* @var string
* @link http://book.cakephp.org/2.0/ja/models/model-attributes.html#usetable
*/
public $useTable = 'topics';
/**
* 検索結果取得のオプション生成
*
* @param int $status ステータス
* @param array $requests 条件リクエスト
* @return array
*/
public function getQueryOptions($status, $requests = array()) {
$options = parent::getQueryOptions('0', array());
$options['fields'] = Hash::merge(
array(
$this->alias . '.id',
$this->alias . '.frame_id',
$this->alias . '.title',
$this->alias . '.title_icon',
$this->alias . '.summary',
$this->alias . '.path',
$this->alias . '.modified',
),
//Categoryフィールド
array_map(function ($field) {
return 'Category.' . $field;
}, Hash::get($this->belongsTo, 'Category.fields', array())),
//CategoriesLanguageフィールド
array_map(function ($field) {
return 'CategoriesLanguage.' . $field;
}, Hash::get($this->belongsTo, 'CategoriesLanguage.fields', array())),
//Languageフィールド
array_map(function ($field) {
return 'Language.' . $field;
}, Hash::get($this->belongsTo, 'Language.fields', array())),
//Roomフィールド
array_map(function ($field) {
return 'Room.' . $field;
}, Hash::get($this->belongsTo, 'Room.fields', array())),
//RoomsLanguageフィールド
array_map(function ($field) {
return 'RoomsLanguage.' . $field;
}, Hash::get($this->belongsTo, 'RoomsLanguage.fields', array())),
//Blockフィールド
array_map(function ($field) {
return 'Block.' . $field;
}, Hash::get($this->belongsTo, 'Block.fields', array())),
//BlocksLanguageフィールド
array_map(function ($field) {
return 'BlocksLanguage.' . $field;
}, Hash::get($this->belongsTo, 'BlocksLanguage.fields', array())),
//Pluginフィールド
array_map(function ($field) {
return 'Plugin.' . $field;
}, Hash::get($this->belongsTo, 'Plugin.fields', array())),
//TrackableCreatorフィールド
Hash::get($this->belongsTo, 'TrackableCreator.fields', array()),
//TrackableUpdaterフィールド
Hash::get($this->belongsTo, 'TrackableUpdater.fields', array())
);
//期間の指定
$conditions = $options['conditions'];
if (Hash::get($requests, 'period_start')) {
$periodStart = (new NetCommonsTime)->toServerDatetime(Hash::get($requests, 'period_start'));
$conditions[$this->alias . '.modified >='] = $periodStart;
}
if (Hash::get($requests, 'period_end')) {
$date = new DateTime(Hash::get($requests, 'period_end'));
// 当日を含むため+1日 例:period_end=2018-3-11の場合、3-11 0:00より小さい日を検索するため、3-11が含まれないため、+1日した3-12 0:00で検索して当日を含める
$date->modify('+1 day');
$periodEnd = (new NetCommonsTime)->toServerDatetime($date->format('Y-m-d'));
$conditions[$this->alias . '.modified <'] = $periodEnd;
}
//プラグインの指定
if (Hash::get($requests, 'plugin_key')) {
$conditions[$this->alias . '.plugin_key'] = Hash::get($requests, 'plugin_key');
}
//ルームの指定
if (Hash::get($requests, 'target_room_id')) {
$conditions[$this->alias . '.room_id'] = Hash::get($requests, 'target_room_id');
}
//ブロックの指定
if (Hash::get($requests, 'block_id')) {
$conditions[$this->alias . '.block_id'] = Hash::get($requests, 'block_id');
}
//フリーワード
if (Hash::get($requests, 'keyword')) {
$conditions[] = $this->getStringCondition(
$this->alias . '.search_contents',
Hash::get($requests, 'keyword'),
Hash::get($requests, 'where_type', self::WHERE_TYPE_AND)
);
}
//ハンドルの指定
if (Hash::get($requests, 'handle')) {
$conditions[] = $this->getStringCondition(
'TrackableCreator.handlename',
Hash::get($requests, 'handle'),
Hash::get($requests, 'where_type', self::WHERE_TYPE_AND)
);
}
$options['conditions'] = $conditions;
return $options;
}
/**
* 文字列フィールドの条件取得
*
* @param string $field フィールド名
* @param string $searchValue 検索値
* @param int $whereType 条件タイプ
* @return array
*/
public function getStringCondition($field, $searchValue, $whereType) {
if ($whereType === self::WHERE_TYPE_PHRASE) {
$values = array($searchValue);
} else {
$values = preg_split('/[\s, ]+/u', $searchValue);
}
$conditions = array();
//暫定対処。後々、パフォーマンスを考慮し、MySQL5.6では、MATCH AGAINSTを使うようにする
//if (SiteSettingUtil::read('Search.type') === SiteSetting::DATABASE_SEARCH_MATCH_AGAIN) {
// if ($whereType === self::WHERE_TYPE_OR) {
// $values = array_map(function ($val) {
// return '"' . $val . '"';
// }, $values);
// } else {
// $values = array_map(function ($val) {
// return '+"' . $val . '"';
// }, $values);
// }
// $conditions['MATCH (' . $field . ') AGAINST (? IN BOOLEAN MODE)'] = implode(' ', $values);
//} else {
$conds = array();
foreach ($values as $val) {
$conds[] = array($field . ' LIKE' => '%' . $val . '%');
}
if ($whereType === self::WHERE_TYPE_OR) {
$conditions['OR'] = $conds;
} elseif ($whereType === self::WHERE_TYPE_PHRASE) {
$conditions = $conds;
} else {
$conditions['AND'] = $conds;
}
//}
return $conditions;
}
}