1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee\Modules\Nodes;
13
14 use ICanBoogie\ActiveRecord\Query;
15 use ICanBoogie\I18n;
16
17 use Brickrouge\A;
18 use Brickrouge\Element;
19 use Brickrouge\Pager;
20 use Brickrouge\Text;
21
22 class AdjustNode extends Element
23 {
24 const T_CONSTRUCTOR = '#adjust-constructor';
25
26 static protected function add_assets(\Brickrouge\Document $document)
27 {
28 parent::add_assets($document);
29
30 $document->css->add(DIR . 'public/module.css');
31 $document->js->add(DIR . 'public/module.js');
32 }
33
34 public function __construct(array $attributes=[])
35 {
36 parent::__construct('div', $attributes + [
37
38 self::T_CONSTRUCTOR => 'nodes',
39 self::WIDGET_CONSTRUCTOR => 'AdjustNode',
40
41 'data-adjust' => 'adjust-node'
42
43 ]);
44 }
45
46 47 48
49 protected function alter_class_names(array $class_names)
50 {
51 return parent::alter_class_names($class_names) + [
52
53 'widget-adjust-node' => true
54
55 ];
56 }
57
58 protected function render_inner_html()
59 {
60 $rc = new Element('input', [
61
62 'type' => 'hidden',
63 'name' => $this['name'],
64 'value' => $this['value']
65
66 ]) . parent::render_inner_html();
67
68 $constructor = $this[self::T_CONSTRUCTOR];
69
70 $rc .= '<div class="search">';
71 $rc .= new Text([ 'class' => 'search', 'placeholder' => I18n\t('Search') ]);
72 $rc .= $this->get_results([ 'selected' => $this['value'] ], $constructor);
73 $rc .= '</div>';
74
75 $this->dataset['constructor'] = $constructor;
76
77 return $rc;
78 }
79
80 public function get_results(array $options=[], $constructor='nodes')
81 {
82 $options += [
83
84 'page' => null,
85 'search' => null,
86 'selected' => null
87
88 ];
89
90 list($records, $range) = $this->get_records($constructor, $options);
91
92 $rc = $records ? $this->render_records($records, $range, $options) : $this->get_placeholder($options);
93
94 return '<div class="results">' . $rc . '</div>';
95 }
96
97 protected function get_records($constructor, array $options, $limit=10)
98 {
99 global $core;
100
101 $model = $core->models[$constructor];
102
103 if ($constructor == 'nodes')
104 {
105 $query = new Query($model);
106 }
107 else
108 {
109 $query = $model->filter_by_constructor($constructor);
110 }
111
112 $search = $options['search'];
113
114 if ($search)
115 {
116 $conditions = '';
117 $conditions_args = [];
118 $words = explode(' ', trim($options['search']));
119 $words = array_map('trim', $words);
120
121 foreach ($words as $word)
122 {
123 $conditions .= ' AND title LIKE ?';
124 $conditions_args[] = '%' . $word . '%';
125 }
126
127 $query->where(substr($conditions, 4), $conditions_args);
128 }
129
130 $query->visible;
131
132 $count = $query->count;
133 $page = $options['page'];
134 $selected = $options['selected'];
135
136 if ($selected && $page === null)
137 {
138 $ids = $query->select('nid')->order('updated_at DESC')->all(\PDO::FETCH_COLUMN);
139 $positions = array_flip($ids);
140 $pos = isset($positions[$selected]) ? $positions[$selected] : 0;
141 $page = floor($pos / $limit);
142 $ids = array_slice($ids, $page * $limit, $limit);
143 $records = $ids ? $model->find($ids) : null;
144 }
145 else
146 {
147 $records = $query->order('updated_at DESC')->limit($page * $limit, $limit)->all;
148 }
149
150 return [ $records, [
151
152 Pager::T_COUNT => $count,
153 Pager::T_LIMIT => $limit,
154 Pager::T_POSITION => $page
155
156 ] ];
157 }
158
159 protected function render_records($records, array $range, array $options)
160 {
161 $selected = $options['selected'];
162
163 $rc = '<ul class="records">';
164
165 foreach ($records as $record)
166 {
167 $rc .= $record->nid == $selected ? '<li class="selected">' : '<li>';
168 $rc .= $this->render_record($record, $selected, $range, $options) . '</li>';
169 }
170
171 $n = count($records);
172 $limit = $range[Pager::T_LIMIT];
173
174 if ($n < $limit)
175 {
176 $rc .= str_repeat('<li class="empty"></li>', $limit - $n);
177 }
178
179 $rc .= '</ul>';
180
181 $rc .= new Element\Nodes\Pager('div', $range + []);
182
183 return $rc;
184 }
185
186 protected function render_record(\Icybee\Modules\Nodes\Node $record, $selected, array $range, array $options)
187 {
188 $recordid = $record->nid;
189
190 return new A(\ICanBoogie\shorten($record->title), '#', [
191
192 'data-nid' => $recordid,
193 'data-title' => $record->title
194
195 ]);
196 }
197
198 protected function get_placeholder(array $options)
199 {
200 $search = $options['search'];
201
202 return '<div class="no-response alert undissmisable">' .
203
204 (
205 $search
206 ? I18n\t('Aucun enregistrement ne correspond aux termes de recherche spécifiés (%search)', [ '%search' => $search ])
207 : I18n\t("Il n'y a pas d'enregistrements")
208 )
209
210 . '</div>';
211 }
212 }
213
214 namespace Brickrouge\Widget;
215
216 class AdjustNode extends \Icybee\Modules\Nodes\AdjustNode
217 {
218
219 }