Completed
Push — develop ( 7d6742...1c56f4 )
by John
02:09
created

RelationLookup::loadAllByAttribute()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
rs 9.504
cc 4
nc 8
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Alpha\Model\Type;
4
5
use Alpha\Model\ActiveRecord;
6
use Alpha\Util\Service\ServiceFactory;
7
use Alpha\Exception\FailedLookupCreateException;
8
use Alpha\Exception\IllegalArguementException;
9
use Alpha\Exception\AlphaException;
10
use Alpha\Util\Config\ConfigProvider;
11
use Alpha\Util\Logging\Logger;
12
use ReflectionClass;
13
14
/**
15
 * The RelationLookup complex data type.  Used to store object2object lookup tables for
16
 * MANY-TO-MANY relationships between record objects.
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) 2019, 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 RelationLookup extends ActiveRecord implements TypeInterface
58
{
59
    /**
60
     * The ID of the left business object in the relation.
61
     *
62
     * @var \Alpha\Model\Type\Integer
63
     *
64
     * @since 1.0
65
     */
66
    protected $leftID;
67
68
    /**
69
     * The ID of the right business object in the relation.
70
     *
71
     * @var \Alpha\Model\Type\Integer
72
     *
73
     * @since 1.0
74
     */
75
    protected $rightID;
76
77
    /**
78
     * The name of the left business object class in the relation.
79
     *
80
     * @var string
81
     *
82
     * @since 1.0
83
     */
84
    private $leftClassName;
85
86
    /**
87
     * The name of the right business object class in the relation.
88
     *
89
     * @var string
90
     *
91
     * @since 1.0
92
     */
93
    private $rightClassName;
94
95
    /**
96
     * Trace logger.
97
     *
98
     * @var \Alpha\Util\Logging\Logger
99
     *
100
     * @since 1.0
101
     */
102
    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...
103
104
    /**
105
     * an array of data display labels for the class properties.
106
     *
107
     * @var array
108
     *
109
     * @since 1.0
110
     */
111
    protected $dataLabels = array('ID' => 'RelationLookup ID#', 'leftID' => 'Left Record ID#', 'rightID' => 'Right Record ID#');
112
113
    /**
114
     * The message to display to the user when validation fails.
115
     *
116
     * @var string
117
     *
118
     * @since 1.0
119
     */
120
    protected $helper = 'Not a valid RelationLookup value!';
121
122
    /**
123
     * The constructor.
124
     *
125
     * @throws \Alpha\Exception\FailedLookupCreateException
126
     * @throws \Alpha\Exception\IllegalArguementException
127
     *
128
     * @since 1.0
129
     */
130
    public function __construct($leftClassName, $rightClassName)
131
    {
132
        self::$logger = new Logger('RelationLookup');
133
        self::$logger->debug('>>__construct(leftClassName=['.$leftClassName.'], rightClassName=['.$rightClassName.'])');
134
135
        // ensure to call the parent constructor
136
        parent::__construct();
137
138
        if (empty($leftClassName) || empty($rightClassName)) {
139
            throw new IllegalArguementException('Cannot create RelationLookup object without providing the left and right class names!');
140
        }
141
142
        $this->leftClassName = $leftClassName;
143
        $this->rightClassName = $rightClassName;
144
145
        $this->leftID = new Integer();
146
        $this->rightID = new Integer();
147
148
        $this->markTransient('leftClassName');
149
        $this->markTransient('rightClassName');
150
        $this->markTransient('helper');
151
        $this->markTransient('TABLE_NAME');
152
153
        // add a unique composite key to these fields
154
        $this->markUnique('leftID', 'rightID');
155
156
        // make sure the lookup table exists
157
        if (!$this->checkTableExists() && ActiveRecord::isInstalled()) {
158
            // first make sure that the two Record tables exist before relating them with a lookup table
159
            if (ActiveRecord::checkRecordTableExists($leftClassName) && ActiveRecord::checkRecordTableExists($rightClassName)) {
160
                $this->makeTable();
161
            } else {
162
                throw new FailedLookupCreateException('Error trying to create a lookup table ['.$this->getTableName().'], as tables for records ['.$leftClassName.'] or ['.$rightClassName.'] don\'t exist!');
163
            }
164
        }
165
166
        self::$logger->debug('<<__construct');
167
    }
168
169
    /**
170
     * Get the leftClassName value.
171
     *
172
     * @return string
173
     *
174
     * @since 1.0
175
     */
176
    public function getLeftClassName()
177
    {
178
        return $this->leftClassName;
179
    }
180
181
    /**
182
     * Get the rightClassName value.
183
     *
184
     * @return string
185
     *
186
     * @since 1.0
187
     */
188
    public function getRightClassName()
189
    {
190
        return $this->rightClassName;
191
    }
192
193
    /**
194
     * Custom getter for the TABLE_NAME, which can't be static in this class due to
195
     * the lookup tablenames being different each time.
196
     *
197
     * @return string
198
     *
199
     * @since 1.0
200
     *
201
     * @throws \Alpha\Exception\AlphaException
202
     */
203
    public function getTableName()
204
    {
205
        if (isset($this->leftClassName) && isset($this->rightClassName)) {
206
            $leftClass = new ReflectionClass($this->leftClassName);
207
            $left = $leftClass->getShortname();
208
            $rightClass = new ReflectionClass($this->rightClassName);
209
            $right = $rightClass->getShortname();
210
            self::$logger->debug('Setting table name to ['.$left.'2'.$right.']');
211
212
            return $left.'2'.$right;
213
        } else {
214
            throw new AlphaException('No table name set for the class ['.get_class($this).'], left or right class name(s) missing');
215
        }
216
    }
217
218
    /**
219
     * This custom version provides the left/right class names to the business object constructor, required
220
     * for RelationLookup objects.
221
     *
222
     * (non-PHPdoc)
223
     *
224
     * @see Alpha\Model\ActiveRecord::loadAllByAttribute()
225
     */
226
    public function loadAllByAttribute($attribute, $value, $start = 0, $limit = 0, $orderBy = 'ID', $order = 'ASC', $ignoreClassType = false, $constructorArgs = array())
227
    {
228
        if (!isset(self::$logger)) {
229
            self::$logger = new Logger('RelationLookup');
230
        }
231
232
        self::$logger->debug('>>loadAllByAttribute(attribute=['.$attribute.'], value=['.$value.'], start=['.$start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.'], constructorArgs=['.print_r($constructorArgs, true).']');
233
234
        if (method_exists($this, 'before_loadAllByAttribute_callback')) {
235
            $this->{'before_loadAllByAttribute_callback'}();
236
        }
237
238
        $config = ConfigProvider::getInstance();
239
240
        $provider = ServiceFactory::getInstance($config->get('db.provider.name'), 'Alpha\Model\ActiveRecordProviderInterface');
241
        $provider->setRecord($this);
242
        $objects = $provider->loadAllByAttribute($attribute, $value, $start, $limit, $orderBy, $order, $ignoreClassType, array($this->leftClassName, $this->rightClassName));
243
244
        if (method_exists($this, 'after_loadAllByAttribute_callback')) {
245
            $this->{'after_loadAllByAttribute_callback'}();
246
        }
247
248
        self::$logger->debug('<<loadAllByAttribute ['.count($objects).']');
249
250
        return $objects;
251
    }
252
253
    /**
254
     * Getter for the validation helper string.
255
     *
256
     * @return string
257
     *
258
     * @since 1.0
259
     */
260
    public function getHelper()
261
    {
262
        return $this->helper;
263
    }
264
265
    /**
266
     * Set the validation helper text.
267
     *
268
     * @param string $helper
269
     *
270
     * @since 1.0
271
     */
272
    public function setHelper($helper)
273
    {
274
        $this->helper = $helper;
275
    }
276
277
    /**
278
     * Returns an array of the IDs of the related objects.
279
     *
280
     * @return integer[]
281
     *
282
     * @since 1.0
283
     */
284
    public function getValue()
285
    {
286
        return array($this->leftID->getValue(), $this->rightID->getValue());
287
    }
288
289
    /**
290
     * Used to set the IDs of the related objects.  Pass a two-item array of IDs, the first
291
     * one being the left object ID, the second being the right.
292
     *
293
     * @param string[] $IDs
294
     *
295
     * @since 1.0
296
     *
297
     * @throws \Alpha\Exception\IllegalArguementException
298
     */
299
    public function setValue($IDs)
300
    {
301
        try {
302
            $this->leftID->setValue($IDs[0]);
303
            $this->rightID->setValue($IDs[1]);
304
        } catch (\Exception $e) {
305
            throw new IllegalArguementException('Array value passed to setValue is not valid ['.var_export($IDs, true).'], array should contain two IDs');
306
        }
307
    }
308
309
    /**
310
     * Used to convert the object to a printable string.
311
     *
312
     * @return string
313
     *
314
     * @since 1.0
315
     */
316
    public function __toString()
317
    {
318
        return strval($this->getTableName());
319
    }
320
}
321