Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

ColumnFactory::__call()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 15
nc 5
nop 2
dl 0
loc 27
ccs 0
cts 16
cp 0
crap 30
rs 8.439
c 0
b 0
f 0
1
<?php
2
namespace Elgg\Views\TableColumn;
3
4
use Elgg\Values;
5
use Elgg\Views\TableColumn;
6
7
/**
8
 * Factory for table column objects
9
 *
10
 * `elgg_list_entities()` can output tables by specifying `$options['list_type'] = 'table'` and
11
 * by providing an array of TableColumn objects to `$options['columns']`. This service, available
12
 * as `elgg()->table_columns` provides methods to create column objects based around existing views
13
 * like `page/components/column/*`, properties, or methods.
14
 *
15
 * Numerous pre-existing methods are provided via `__call()` magic. See this method to find out how
16
 * to add your own methods, override the existing ones, or completely replace a method via hook.
17
 *
18
 * @internal Use elgg()->table_columns to access the instance of this.
19
 *
20
 * @method TableColumn admin($heading = null, $vars = [])
21
 * @method TableColumn banned($heading = null, $vars = [])
22
 * @method TableColumn container($heading = null, $vars = [])
23
 * @method TableColumn excerpt($heading = null, $vars = [])
24
 * @method TableColumn icon($heading = null, $vars = [])
25
 * @method TableColumn item($heading = null, $vars = [])
26
 * @method TableColumn language($heading = null, $vars = [])
27
 * @method TableColumn link($heading = null, $vars = [])
28
 * @method TableColumn owner($heading = null, $vars = [])
29
 * @method TableColumn time_created($heading = null, $vars = [])
30
 * @method TableColumn time_updated($heading = null, $vars = [])
31
 * @method TableColumn description($heading = null)
32
 * @method TableColumn email($heading = null)
33
 * @method TableColumn name($heading = null)
34
 * @method TableColumn type($heading = null)
35
 * @method TableColumn user($heading = null, $vars = [])
36
 * @method TableColumn username($heading = null)
37
 * @method TableColumn getSubtype($heading = null)
38
 * @method TableColumn getDisplayName($heading = null)
39
 * @method TableColumn getMimeType($heading = null)
40
 * @method TableColumn getSimpleType($heading = null)
41
 */
42
class ColumnFactory {
43
44
	/**
45
	 * Make a column from one of the page/components/column/* views.
46
	 *
47
	 * @param string $name    Column name (view will be "page/components/column/$name")
48
	 * @param string $heading Optional heading
49
	 * @param array  $vars    View vars (item, item_vars, and type will be merged in)
50
	 *
51
	 * @return ViewColumn
52
	 */
53
	public function fromView($name, $heading = null, $vars = []) {
54
		$view = "page/components/column/$name";
55
56
		if (!is_string($heading)) {
57
			if (elgg_language_key_exists("table_columns:fromView:$name")) {
58
				$heading = elgg_echo("table_columns:fromView:$name");
59
			} else {
60
				$title = str_replace('_', ' ', $name);
61
				$heading = elgg_ucwords($title);
62
			}
63
		}
64
65
		return new ViewColumn($view, $heading, $vars);
66
	}
67
68
	/**
69
	 * Make a column by reading a property of the item
70
	 *
71
	 * @param string $name    Property name. e.g. "description", "email", "type"
72
	 * @param string $heading Heading
73
	 *
74
	 * @return CallableColumn
75
	 */
76
	public function fromProperty($name, $heading = null) {
77
		if (!is_string($heading)) {
78
			if (elgg_language_key_exists("table_columns:fromProperty:$name")) {
79
				$heading = elgg_echo("table_columns:fromProperty:$name");
80
			} else {
81
				$title = str_replace('_', ' ', $name);
82
				$heading = elgg_ucwords($title);
83
			}
84
		}
85
86
		$renderer = function ($item) use ($name) {
87
			return $item->{$name};
88
		};
89
90
		return new CallableColumn($renderer, $heading);
91
	}
92
93
	/**
94
	 * Make a column by calling a method on the item
95
	 *
96
	 * @param string $name    Method name. e.g. "getSubtype", "getDisplayName"
97
	 * @param string $heading Heading
98
	 * @param array  $args    Method arguments
99
	 *
100
	 * @return CallableColumn
101
	 */
102
	public function fromMethod($name, $heading = null, $args = []) {
103
		if (!is_string($heading)) {
104
			if (elgg_language_key_exists("table_columns:fromMethod:$name")) {
105
				$heading = elgg_echo("table_columns:fromMethod:$name");
106
			} else {
107
				$title = str_replace('_', ' ', $name);
108
				$heading = elgg_ucwords($title);
109
			}
110
		}
111
112
		$renderer = function ($item) use ($name, $args) {
113
			return call_user_func_array([$item, $name], $args);
114
		};
115
116
		return new CallableColumn($renderer, $heading);
117
	}
118
119
	/**
120
	 * Provide additional methods via hook and specified language keys.
121
	 *
122
	 * First, the hook `table_columns:call` is called. Details in `docs/guides/hooks-list.rst`.
123
	 *
124
	 * Then it checks existence of 3 language keys in order to defer processing to a local method:
125
	 *
126
	 * - "table_columns:fromView:$name" -> uses $this->fromView($name, ...).
127
	 * - "table_columns:fromProperty:$name" -> uses $this->fromProperty($name, ...).
128
	 * - "table_columns:fromMethod:$name" -> uses $this->fromMethod($name, ...).
129
	 *
130
	 * See the `from*()` methods for details.
131
	 *
132
	 * @param string $name      Method name
133
	 * @param array  $arguments Arguments
134
	 *
135
	 * @return TableColumn
136
	 */
137
	public function __call($name, $arguments) {
138
		// allow hook to hijack magic methods
139
		$column = elgg_trigger_plugin_hook('table_columns:call', $name, [
0 ignored issues
show
Bug introduced by Steve Clay
Are you sure the assignment to $column is correct as elgg_trigger_plugin_hook...uments' => $arguments)) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
140
			'arguments' => $arguments,
141
		]);
142
		if ($column instanceof TableColumn) {
143
			return $column;
144
		}
145
146
		if (elgg_language_key_exists("table_columns:fromView:$name")) {
147
			array_unshift($arguments, $name);
148
			return call_user_func_array([$this, 'fromView'], $arguments);
149
		}
150
151
		if (elgg_language_key_exists("table_columns:fromProperty:$name")) {
152
			array_unshift($arguments, $name);
153
			return call_user_func_array([$this, 'fromProperty'], $arguments);
154
		}
155
156
		if (elgg_language_key_exists("table_columns:fromMethod:$name")) {
157
			array_unshift($arguments, $name);
158
			return call_user_func_array([$this, 'fromMethod'], $arguments);
159
		}
160
161
		// empty column and error
162
		_elgg_services()->logger->error(__CLASS__ . ": No method defined '$name'");
163
		return new CallableColumn([Values::class, 'getNull'], '');
164
	}
165
}
166