This repository has been archived by the owner on Jan 6, 2020. It is now read-only.
/
ft.nsm_entry_select.php
376 lines (332 loc) · 9.89 KB
/
ft.nsm_entry_select.php
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* NSM Example Addon Fieldtype
*
* @package NSMEntrySelect
* @version 0.0.1
* @author Leevi Graham <http://newism.com.au>
* @copyright Copyright (c) 2007-2010 Newism
* @license Commercial - please see LICENSE file included with this distribution
* @see http://expressionengine.com/public_beta/docs/development/extensions.html
*
**/
class Nsm_entry_select_ft extends EE_Fieldtype
{
/**
* Field info - Required
*
* @access public
* @var array
*/
public $info = array(
'name' => 'NSM Entry Select',
'version' => '0.0.2'
);
/**
* UI Modes
*
* @access private
* @var array
*/
private static $ui_modes = array(
'select',
'multi_select',
'autocomplete'
);
/**
* Constructor
*
* @access public
*
* Calls the parent constructor
*/
public function __construct()
{
parent::__construct();
$this->EE->load->model('channel_model');
// create a cache
if(!isset($this->EE->session->cache[__CLASS__]))
{
$this->EE->session->cache[__CLASS__] = array();
$this->EE->session->cache[__CLASS__]["entry_data"] = array();
$this->EE->session->cache[__CLASS__]["channel_custom_fields"] = array();
}
}
/**
* Display the settings form for each custom field
*
* @access public
* @param $data mixed The field settings
* @return string Override the field custom settings with custom html
*
* In this case we add an extra row to the table. Not sure how the table is built
*/
public function display_settings($data)
{
$this->EE->lang->loadfile('nsm_entry_select');
$this->EE->load->model('channel_model');
$data = array_merge(array(
"field_channels" => array(),
"field_ui_mode" => FALSE,
"field_size" => 1
), $data);
$entry_channels_query = $this->EE->channel_model->get_channels()->result();
$entry_channels = array();
foreach ($entry_channels_query as $channel) {
$entry_channels[$channel->channel_id] = $channel->channel_title;
}
$this->EE->table->add_row(
form_hidden($this->field_id.'_field_fmt', 'none') .
form_hidden('field_show_fmt', 'n') .
lang("Restrict entry selection to:", 'field_channels'),
form_multiselect($this->field_id.'_field_settings[field_channels][]', $entry_channels, $data["field_channels"], "id='field_channels'")
);
$select_opts = array();
foreach (self::$ui_modes as $key)
$select_opts[$key] = lang($key);
$this->EE->table->add_row(
lang("UI Mode:", 'field_ui_mode'),
form_dropdown($this->field_id.'_field_settings[field_ui_mode]', $select_opts, $data["field_ui_mode"], "id='field_ui_mode'")
);
$this->EE->table->add_row(
lang("Size", 'field_size')
. "<br />Determines the multi-select height and number of results returned in the autocomplete",
form_input($this->field_id.'_field_settings[field_size]', $data["field_size"], "id='field_size'")
);
}
/**
* Save the custom field settings
*
* @return boolean Valid or not
*/
public function save_settings()
{
$new_settings = $this->EE->input->post('nsm_entry_select_field_settings');
return $new_settings;
}
/**
* Display the field in the publish form
*
* @access public
* @param $data String Contains the current field data. Blank for new entries.
* @return String The custom field HTML
*/
public function display_field($data)
{
if(!is_array($data))
$data = explode("|", $data);
switch ($this->settings['field_ui_mode']) {
case "select":
return $this->_uiSelect($this->field_id, $this->settings['field_channels'], $data);
break;
case "multi_select":
return $this->_uiSelect($this->field_id, $this->settings['field_channels'], $data, TRUE, $this->settings['field_size']);
break;
case "auto_complete":
return "Autocomplete coming soon!";
break;
}
}
/**
* Publish form validation
*
* @param $data array Contains the submitted field data.
* @return mixed TRUE or an error message
*/
public function validate($data)
{
return TRUE;
}
/**
* Pre-process the data and return a string
*
* @access public
* @param array data The selected entry channels
* @return string Concatenated string f entry channels
*/
public function save($data){
$this->EE->load->helper('custom_field');
return encode_multi_field($data);
}
/**
* Replaces the custom field tag
*
* @access public
* @param $data string Contains the field data (or prepped data, if using pre_process)
* @param $params array Contains field parameters (if any)
* @param $tagdata mixed Contains data between tag (for tag pairs) FALSE for single tags
* @return string The HTML replacing the tag
*
*/
public function replace_tag($data, $params = FALSE, $tagdata = FALSE)
{
// print("<pre>" . print_r($params, TRUE) . "</pre>");
$this->EE->load->helper('custom_field');
$entries = decode_multi_field($data);
$params = array_merge(array(
"backspace" => FALSE,
"glue" => ", ",
"multi_field" => FALSE,
"multi_field_glue" => ", ",
"value" => "entry_id",
"prefix" => "es:"
), (array) $params);
$entries = $this->_getEntryData($entries, $params);
return ($tagdata) ? $this->_parseMulti($entries, $params, $tagdata) : $this->_parseSingle($entries, $params);
}
/**
* Parse a single tag
*
* @access private
* @param $entries array The entry ids
* @param $params array the tag params
* @return string The entry ids concatenated with glue
*/
private function _parseSingle($entries, $params)
{
$ret = array();
foreach ($entries as $entry_id => $entry)
{
if(self::_isTrue($params["multi_field"]))
{
$entry[$params["value"]] = implode($params["multi_field_glue"], decode_multi_field($entry[$params["value"]]));
}
$ret[] = $entry[$params["value"]];
}
return implode($params["glue"], $ret);
}
/**
* Parse a tag pair
*
* @access private
* @param $entries array The entry ids
* @param $params array the tag params
* @param $tagdata string The data between the tag pair
* @return string The entry ids concatenated with glue
*/
private function _parseMulti($entries, $params, $tagdata)
{
$chunk = '';
foreach($entries as $count => $entry)
{
$vars['count'] = $count + 1;
foreach ($entry as $key => $value)
{
$vars[$params["prefix"] . $key] = $value;
}
$tmp = $this->EE->functions->prep_conditionals($tagdata, $vars);
$chunk .= $this->EE->functions->var_swap($tmp, $vars);
}
if ($params['backspace'])
{
$chunk = substr($chunk, 0, - $params['backspace']);
}
return $chunk;
}
/**
* Get the entry data from the DB
*
* @access private
* @param $entries array The entry ids
* @param $params array the tag params
* @return array Entries with DB data
*/
private function _getEntryData($entries, $params)
{
$required_entries = $entries;
foreach($required_entries as $k => $v)
{
if(array_key_exists($v, $this->EE->session->cache[__CLASS__]))
{
unset($required_entries[$k]);
}
}
if(!empty($required_entries))
{
$this->EE->db->from("exp_channel_titles")
->join("exp_channel_data", 'exp_channel_titles.entry_id = exp_channel_data.entry_id')
->where_in("exp_channel_titles.entry_id", $required_entries);
$query = $this->EE->db->get();
foreach ($query->result_array() as $entry)
{
$this->EE->session->cache[__CLASS__]["entry_data"][$entry["entry_id"]] = $entry;
}
}
$ret = array();
foreach ($entries as $entry_id)
{
if(!isset($this->EE->session->cache[__CLASS__]["entry_data"][$entry_id]))
continue;
$ret[] = $this->EE->session->cache[__CLASS__]["entry_data"][$entry_id];
}
return $ret;
}
/**
* Create a select UI
*
* @param $field_id string The field id
* @param $channels array Entry channels we are selecting entries from
* @param $selected_entries array Previous selected entries
* @param $multiple boolean Does this select accept multiple selections
* @param $size int Size of the select box
* @return str HTML for UI
*/
private function _uiSelect($field_id, array $channels, array $selected_entries = array(), $multiple = FALSE, $size = 1)
{
if(empty($channels))
return lang("No channels have been selected in the field settings");
$entry_query = $this->EE->db->query("SELECT
exp_channel_titles.entry_id AS entry_id,
exp_channel_titles.title AS entry_title,
exp_channels.channel_title AS channel_title,
exp_channels.channel_id AS channel_id
FROM
exp_channel_titles
INNER JOIN
exp_channels
ON
exp_channel_titles.channel_id = exp_channels.channel_id
WHERE
exp_channels.channel_id IN (" . implode(",",$channels) . ")
ORDER BY
exp_channels.channel_id ASC , exp_channel_titles.title ASC ");
if($entry_query->num_rows == 0)
return lang('No channel entries were found for this field');
$attrs = ($multiple) ? 'multiple="multiple" size="'.$size.'"' : '';
$r = "\n<select id='field_id_" . $this->field_id . "' name='field_id_" . $this->field_id . "[]'". $attrs ." >";
if(!$multiple)
$r .= "<option value=''>".lang('Do not associate an entry with this entry')."</option>";
$channel = null;
foreach ($entry_query->result_array() as $entry)
{
if($channel != $entry['channel_title'])
{
// if this is not the first channel
if($channel != null)
{
// close the optgroup
$r .= "\n\t</optgroup>";
}
// set the current channel
$channel = $entry['channel_title'];
// open another opt channel
$r .= "\n\t<optgroup label='" . $entry['channel_title'] ."'>";
}
$selected = (in_array($entry['entry_id'], $selected_entries)) ? " selected='selected' " : "";
$r .= "\n\t\t<option value='" . $entry['entry_id'] . "'" . $selected . " > " . $entry['entry_title'] . "</option>";
}
$r .= "</select>";
return $r;
}
/**
* Checks if a param value is true
*
* @access private
* @param $value mixed The param value
* @return boolean
*/
private static function _isTrue($value){
return in_array($value, array("yes", "y", "1", TRUE, "true", "TRUE"));
}
}
//END CLASS