Completed
Push — develop ( 4bd701...470d2f )
by John
02:48
created

DEnum::saveIfNew()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 17
rs 8.8571
c 1
b 0
f 1
cc 5
eloc 10
nc 5
nop 0
1
<?php
2
3
namespace Alpha\Model\Type;
4
5
use Alpha\Model\ActiveRecord;
6
use Alpha\Model\ActiveRecordProviderFactory;
7
use Alpha\Model\Type\SmallText;
8
use Alpha\Exception\RecordNotFoundException;
9
use Alpha\Exception\AlphaException;
10
use Alpha\Exception\IllegalArguementException;
11
use Alpha\Util\Config\ConfigProvider;
12
use Alpha\Util\Logging\Logger;
13
14
/**
15
 * The DEnum (Dynamic Enum) complex data type.  Similiar to Enum,
16
 * except list items are stored in a database table and are editable.
17
 *
18
 * @since 1.0
19
 *
20
 * @author John Collins <[email protected]>
21
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
22
 * @copyright Copyright (c) 2017, John Collins (founder of Alpha Framework).
23
 * All rights reserved.
24
 *
25
 * <pre>
26
 * Redistribution and use in source and binary forms, with or
27
 * without modification, are permitted provided that the
28
 * following conditions are met:
29
 *
30
 * * Redistributions of source code must retain the above
31
 *   copyright notice, this list of conditions and the
32
 *   following disclaimer.
33
 * * Redistributions in binary form must reproduce the above
34
 *   copyright notice, this list of conditions and the
35
 *   following disclaimer in the documentation and/or other
36
 *   materials provided with the distribution.
37
 * * Neither the name of the Alpha Framework nor the names
38
 *   of its contributors may be used to endorse or promote
39
 *   products derived from this software without specific
40
 *   prior written permission.
41
 *
42
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
43
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
44
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
45
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
47
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
49
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
53
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
54
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55
 * </pre>
56
 */
57
class DEnum extends ActiveRecord implements TypeInterface
58
{
59
    /**
60
     * An array of valid DEnum options.
61
     *
62
     * @var array
63
     *
64
     * @since 1.0
65
     */
66
    protected $options = array();
67
68
    /**
69
     * The currently selected DEnum option.
70
     *
71
     * @var int
72
     *
73
     * @since 1.0
74
     */
75
    protected $value;
76
77
    /**
78
     * The name of the DEnum used in the database.
79
     *
80
     * @var \Alpha\Model\Type\SmallText
81
     *
82
     * @since 1.0
83
     */
84
    protected $name;
85
86
    /**
87
     * The name of the database table for the class.
88
     *
89
     * @var string
90
     *
91
     * @since 1.0
92
     */
93
    const TABLE_NAME = 'DEnum';
94
95
    /**
96
     * An array of data display labels for the class properties.
97
     *
98
     * @var array
99
     *
100
     * @since 1.0
101
     */
102
    protected $dataLabels = array('ID' => 'DEnum ID#', 'name' => 'Name');
103
104
    /**
105
     * The message to display to the user when validation fails.
106
     *
107
     * @var string
108
     *
109
     * @since 1.0
110
     */
111
    protected $helper = 'Not a valid denum option!';
112
113
    /**
114
     * Trace logger.
115
     *
116
     * @var \Alpha\Util\Logging\Logger
117
     *
118
     * @since 1.2
119
     */
120
    private static $logger = null;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
121
122
    /**
123
     * Constructor that sets up the DEnum options.
124
     *
125
     * @param string $name
126
     */
127
    public function __construct($name = null)
128
    {
129
        self::$logger = new Logger('DEnum');
130
131
        // ensure to call the parent constructor
132
        parent::__construct();
133
134
        $this->markTransient('options');
135
        $this->markTransient('value');
136
        $this->markTransient('helper');
137
138
        $this->name = new SmallText($name);
139
140
        if (isset($name)) {
141
            $this->saveIfNew();
142
        }
143
    }
144
145
    /**
146
     * Saves a new DEnum record with the same name as this instance if one does not already exist
147
     *
148
     * @return void
149
     *
150
     * @since 3.0
151
     */
152
    public function saveIfNew()
153
    {
154
        if (isset($this->name) && $this->checkTableExists()) {
155
            try {
156
                $this->loadByAttribute('name', $this->name);
157
            } catch (RecordNotFoundException $e) {
158
                // DEnum does not exist so create it
159
                $this->save();
160
            }
161
162
            try {
163
                $this->getOptions();
164
            } catch (AlphaException $e) {
165
                self::$logger->warn($e->getMessage());
166
            }
167
        }
168
    }
169
170
    /**
171
     * Setter for the name of the DEnum used in the database.
172
     *
173
     * @param string $name
174
     *
175
     * @since 1.0
176
     */
177
    public function setName($name)
178
    {
179
        $this->name->setValue($name);
180
    }
181
182
    /**
183
     * Get the array of DEnum options from the database.
184
     *
185
     * @param bool $alphaSort
186
     *
187
     * @return array
188
     *
189
     * @since 1.0
190
     *
191
     * @throws \Alpha\Exception\AlphaException
192
     */
193
    public function getOptions($alphaSort = false)
194
    {
195
        try {
196
            $options = new self();
197
            $options->loadByAttribute('name', $this->name->getValue());
198
        } catch (RecordNotFoundException $e) {
199
            throw new AlphaException('Failed to load DEnum '.$this->name->getValue().', not found in database.');
200
        }
201
202
        // now build an array of item indexes to be returned
203
        $count = 0;
204
        $this->options = array();
205
206
        $item = new DEnumItem();
207
208
        foreach ($item->loadItems($options->getID()) as $DEnumItem) {
209
            $this->options[$DEnumItem->getID()] = $DEnumItem->getValue();
210
            ++$count;
211
        }
212
213
        if ($alphaSort) {
214
            asort($this->options, SORT_STRING);
215
        }
216
217
        return $this->options;
218
    }
219
220
    /**
221
     * Getter for the validation helper string.
222
     *
223
     * @return string
224
     *
225
     * @since 1.0
226
     */
227
    public function getHelper()
228
    {
229
        return $this->helper;
230
    }
231
232
    /**
233
     * Set the validation helper text.
234
     *
235
     * @param string $helper
236
     *
237
     * @since 1.0
238
     */
239
    public function setHelper($helper)
240
    {
241
        $this->helper = $helper;
242
    }
243
244
    /**
245
     * Getter for the name.
246
     *
247
     * @return SmallText
248
     *
249
     * @since 1.0
250
     */
251
    public function getName()
252
    {
253
        return $this->name;
254
    }
255
256
    /**
257
     * Used to get the current DEnum item selected index value.
258
     *
259
     * @return int
260
     *
261
     * @since 1.0
262
     */
263
    public function getValue()
264
    {
265
        return $this->value;
266
    }
267
268
    /**
269
     * Used to get the current DEnum item string value.
270
     *
271
     * @return string
272
     *
273
     * @since 1.0
274
     */
275
    public function getDisplayValue()
276
    {
277
        // check to see if the options have already been loaded from the DB
278
        if (empty($this->options)) {
279
            $this->getOptions();
280
        }
281
282
        $val = Integer::zeroPad($this->value);
283
        if (isset($this->options[$val])) {
284
            return $this->options[$val];
285
        } else {
286
            return 'Unknown';
287
        }
288
    }
289
290
    /**
291
     * Used to select the current DEnum item.
292
     *
293
     * @param string $item
294
     *
295
     * @since 1.0
296
     */
297
    public function setValue($item)
298
    {
299
        // check to see if the options have already been loaded from the DB
300
        if (empty($this->options)) {
301
            $this->getOptions();
302
        }
303
304
        // confirm that the item ID provided is a valid key for the options array
305
        if (in_array($item, array_keys($this->options))) {
306
            $this->value = $item;
0 ignored issues
show
Documentation Bug introduced by
The property $value was declared of type integer, but $item is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
307
        } else {
308
            throw new IllegalArguementException($this->getHelper());
309
        }
310
    }
311
312
    /**
313
     * Gets the count from the database of the DEnumItems associated with this object.
314
     *
315
     * @return int
316
     *
317
     * @since 1.0
318
     *
319
     * @throws \Alpha\Exception\AlphaException
320
     */
321
    public function getItemCount()
322
    {
323
        $config = ConfigProvider::getInstance();
324
325
        $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
326
327
        $sqlQuery = 'SELECT COUNT(ID) AS item_count FROM DEnumItem WHERE DEnumID = \''.$this->getID().'\';';
328
329
        $this->setLastQuery($sqlQuery);
330
331
        $result = $provider->query($sqlQuery);
332
333
        if (count($result) > 0 && isset($result[0]['item_count'])) {
334
            return $result[0]['item_count'];
335
        } else {
336
            throw new AlphaException('Failed to get the item count for the DEnum. Database error string is ['.$provider->getLastDatabaseError().']');
337
        }
338
    }
339
340
    /**
341
     * Used to get the DenumItem ID for the given option name.
342
     *
343
     * @param string $optionName
344
     *
345
     * @return int
346
     *
347
     * @since 1.0
348
     */
349
    public function getOptionID($optionName)
350
    {
351
        $denumItem = new DEnumItem();
352
        $denumItem->loadByAttribute('value', $optionName);
353
        $id = $denumItem->getID();
354
355
        if (!empty($id)) {
356
            return $id;
357
        } else {
358
            return 0;
359
        }
360
    }
361
362
    /**
363
     * Used to convert the object to a printable string.
364
     *
365
     * @return string
366
     *
367
     * @since 1.0
368
     */
369
    public function __toString()
370
    {
371
        return strval($this->value);
372
    }
373
}
374