Passed
Push — master ( 409c3f...e5371a )
by Andreas
09:22
created

org_openpsa_relatedto_plugin::get2relatedto()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 12.4085

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 6
nop 0
dl 0
loc 17
ccs 4
cts 12
cp 0.3333
crap 12.4085
rs 9.6111
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package org.openpsa.relatedto
4
 * @author Nemein Oy, http://www.nemein.com/
5
 * @copyright Nemein Oy, http://www.nemein.com/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
/**
10
 * Class for handling "related to" information
11
 *
12
 * @package org.openpsa.relatedto
13
 */
14
class org_openpsa_relatedto_plugin extends midcom_baseclasses_components_plugin
15
{
16
    /**
17
     * Shorthand for creating a relatedto object.
18
     *
19
     * The <i>from</i> object is something that is related to the <em>to</em>
20
     * object.
21
     * For example, if a task is created under a sales project, that task is
22
     * the from object, and the sales project the to object.
23
     *
24
     * @param array $extra Array with the possible extra-properties
25
     */
26 11
    public static function create(object $from_obj, string $from_component, object $to_obj, string $to_component, int $status = null, array $extra = []) : ?org_openpsa_relatedto_dba
27
    {
28 11
        $status ??= org_openpsa_relatedto_dba::CONFIRMED;
29
30 11
        $rel = new org_openpsa_relatedto_dba();
31 11
        $rel->fromClass = get_class($from_obj);
32 11
        $rel->toClass = get_class($to_obj);
33 11
        $rel->fromGuid = $from_obj->guid;
34 11
        $rel->toGuid = $to_obj->guid;
35 11
        $rel->fromComponent = $from_component;
36 11
        $rel->toComponent = $to_component;
37 11
        $rel->status = $status;
38
39 11
        if ($guid = $rel->check_db(false)) {
40 1
            $db_rel = new org_openpsa_relatedto_dba($guid);
41 1
            debug_add("A relation from {$rel->fromClass} #{$rel->fromGuid} to {$rel->toClass} #{$rel->toGuid} already exists, returning this one instead");
42 1
            if ($db_rel->status < $rel->status) {
43 1
                $db_rel->status = $rel->status;
44 1
                $db_rel->update();
45
            }
46 1
            return $db_rel;
47
        }
48
49 11
        foreach ($extra as $extra_key => $extra_value) {
50
            $rel->$extra_key = $extra_value;
51
        }
52
53 11
        if (!$rel->create()) {
54
            debug_add("failed to create link from {$rel->fromClass} #{$rel->fromGuid} to {$rel->toClass} #{$rel->toGuid}, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_WARN);
55
            return null;
56
        }
57
58 11
        return $rel;
59
    }
60
61
    /**
62
     * Parses relatedto information from request, returning either
63
     * existing matching relatedtos or prefilled new ones for creation
64
     */
65 35
    public static function get2relatedto() : array
66
    {
67 35
        $ret = [];
68 35
        if (!array_key_exists('org_openpsa_relatedto', $_REQUEST)) {
69 35
            return $ret;
70
        }
71
        foreach ($_REQUEST['org_openpsa_relatedto'] as $rel_array) {
72
            $rel = new org_openpsa_relatedto_dba();
73
            foreach ($rel_array as $k => $v) {
74
                $rel->$k = $v;
75
            }
76
            if ($guid = $rel->check_db()) {
77
                $rel = new org_openpsa_relatedto_dba($guid);
78
            }
79
            $ret[] = $rel;
80
        }
81
        return $ret;
82
    }
83
84
    /**
85
     * Serializes an array or relatedto objects into GET parameters
86
     *
87
     * NOTE: does not prefix the ? for the first parameter in case this needs
88
     * to be used with some other GET parameters.
89
     */
90 1
    public static function relatedto2get(array $array) : ?string
91
    {
92 1
        $ret = ['org_openpsa_relatedto' => []];
93 1
        foreach ($array as $rel) {
94 1
            if (!midcom::get()->dbfactory->is_a($rel, org_openpsa_relatedto_dba::class)) { //Matches also 'org_openpsa_relatedto'
95
                //Wrong type of object found in array, cruelly abort the whole procedure
96
                return null;
97
            }
98 1
            $entry = [
99 1
                'toGuid' => $rel->toGuid,
100 1
                'toComponent' => $rel->toComponent,
101 1
                'toClass' => $rel->toClass
102 1
            ];
103
104
            //To save GET space we only append these if they have values
105 1
            foreach (['status', 'fromComponent', 'fromClass', 'fromGuid'] as $key) {
106 1
                if ($rel->$key) {
107 1
                    $entry[$key] = $rel->$key;
108
                }
109
            }
110
111 1
            $ret['org_openpsa_relatedto'][] = $entry;
112
        }
113 1
        return http_build_query($ret, '', '&');
114
    }
115
116 4
    public static function add_button(midcom_helper_toolbar $toolbar, string $guid)
117
    {
118 4
        $toolbar->add_item([
119 4
            MIDCOM_TOOLBAR_URL => "__mfa/org.openpsa.relatedto/render/{$guid}/both/",
120 4
            MIDCOM_TOOLBAR_LABEL => midcom::get()->i18n->get_string('view related information', 'org.openpsa.relatedto'),
121 4
            MIDCOM_TOOLBAR_GLYPHICON => 'paperclip',
122 4
        ]);
123
    }
124
125 5
    private static function common_node_toolbar_buttons_sanitycheck(array &$data, string $button_component, $bind_object, string $calling_component) : ?org_openpsa_relatedto_dba
126
    {
127 5
        if (!midcom::get()->componentloader->is_installed($button_component)) {
128
            debug_add("component {$button_component} is not installed", MIDCOM_LOG_ERROR);
129
            return null;
130
        }
131 5
        if (empty($data['node'])) {
132 5
            debug_add("data['node'] not given, trying with siteconfig");
133 5
            $siteconfig = org_openpsa_core_siteconfig::get_instance();
134 5
            $node_guid = $siteconfig->get_node_guid($button_component);
135 5
            if (!$node_guid) {
136
                debug_add("data['node'] not given, and {$button_component} could not be found in siteconfig", MIDCOM_LOG_INFO);
137
                return null;
138
            }
139
140 5
            $nap = new midcom_helper_nav();
141 5
            $data['node'] = $nap->resolve_guid($node_guid);
142 5
            if (empty($data['node'])) {
143
                //Invalid node given/found
144 5
                debug_add("data['node'] is invalid", MIDCOM_LOG_ERROR);
145 5
                return null;
146
            }
147
        }
148
149
        $related_to = new org_openpsa_relatedto_dba();
150
        $related_to->toGuid = $bind_object->guid;
151
        $related_to->toClass = get_class($bind_object);
152
        $related_to->toComponent = $calling_component;
153
        $related_to->fromComponent = $button_component;
154
        $related_to->status = org_openpsa_relatedto_dba::CONFIRMED;
155
156
        return $related_to;
157
    }
158
159 3
    public static function common_toolbar_buttons_defaults() : array
160
    {
161 3
        return [
162 3
            'event' => [
163 3
                'node' => false,
164 3
                'component' => 'org.openpsa.calendar'
165 3
            ],
166 3
            'task'  => [
167 3
                'node' => false,
168 3
                'component' => 'org.openpsa.projects'
169 3
            ],
170 3
            'wikinote' => [
171 3
                'node' => false,
172 3
                'component' => 'net.nemein.wiki',
173 3
                'wikiword'  => false, //Calling component MUST define this key to get a wikinote button
174 3
            ],
175 3
            'document' => [
176 3
                'node' => false,
177 3
                'component' => 'org.openpsa.documents'
178 3
            ],
179 3
        ];
180
    }
181
182 5
    public static function common_node_toolbar_buttons(midcom_helper_toolbar $toolbar, $bind_object, string $calling_component, array $buttons)
183
    {
184 5
        $workflow = new midcom\workflow\datamanager;
185 5
        $toolbar_buttons = [];
186 5
        foreach ($buttons as $mode => $data) {
187 5
            debug_print_r("processing button '{$mode}' with data:", $data);
188 5
            if ($data === false) {
189
                //In case somebody didn't unset() a button from the defaults, just marked it as false
190
                debug_add('data marked as false, skipping (the correct way is to unset() the key)', MIDCOM_LOG_WARN);
191
                continue;
192
            }
193
194 5
            $related_to = self::common_node_toolbar_buttons_sanitycheck($data, $data['component'], $bind_object, $calling_component);
195 5
            if (!$related_to) {
196 5
                debug_add("sanitycheck returned false, skipping", MIDCOM_LOG_WARN);
197 5
                continue;
198
            }
199
            //Remember that switch is also a for statement in PHPs mind, use "continue 2"
200
            switch ($mode) {
201
                case 'event':
202
                    $toolbar_buttons[] = org_openpsa_calendar_interface::get_create_button($data['node'], '?' . self::relatedto2get([$related_to]));
203
                    break;
204
                case 'task':
205
                    if (midcom::get()->auth->can_user_do('midgard:create', null, org_openpsa_projects_task_dba::class)) {
206
                        $toolbar_buttons[] = $workflow->get_button("{$data['node'][MIDCOM_NAV_ABSOLUTEURL]}task/new/?" . self::relatedto2get([$related_to]), [
207
                            MIDCOM_TOOLBAR_LABEL => midcom::get()->i18n->get_string('create task', $data['component']),
208
                            MIDCOM_TOOLBAR_GLYPHICON => 'calendar-check-o',
209
                            MIDCOM_TOOLBAR_OPTIONS => ['data-refresh-opener' => 'true'],
210
                        ]);
211
                    }
212
                    break;
213
                case 'wikinote':
214
                    if (empty($data['wikiword'])) {
215
                        //Wikiword to use not given
216
                        debug_add("data['wikiword'] not given, skipping", MIDCOM_LOG_WARN);
217
                        continue 2;
218
                    }
219
220
                    if (!net_nemein_wiki_interface::node_wikiword_is_free($data['node'], $data['wikiword'])) {
221
                        //Wikiword is already reserved
222
                        //PONDER: append number or something and check again ??
223
                        debug_add("node_wikiword_is_free returned false for '{$data['wikiword']}'", MIDCOM_LOG_WARN);
224
                        continue 2;
225
                    }
226
227
                    $data['wikiword_encoded'] = rawurlencode($data['wikiword']);
228
                    $toolbar_buttons[] = $workflow->get_button("{$data['node'][MIDCOM_NAV_ABSOLUTEURL]}create/?wikiword={$data['wikiword_encoded']}&" . self::relatedto2get([$related_to]), [
229
                        MIDCOM_TOOLBAR_LABEL => midcom::get()->i18n->get_string('create note', $data['component']),
230
                        MIDCOM_TOOLBAR_GLYPHICON => 'sticky-note-o',
231
                        MIDCOM_TOOLBAR_ENABLED => $data['node'][MIDCOM_NAV_OBJECT]->can_do('midgard:create'),
232
                        MIDCOM_TOOLBAR_OPTIONS => ['data-refresh-opener' => 'true'],
233
                    ]);
234
                    break;
235
                case 'document':
236
                    if ($data['node'][MIDCOM_NAV_OBJECT]->can_do('midgard:create')) {
237
                        $toolbar_buttons[] = $workflow->get_button("{$data['node'][MIDCOM_NAV_ABSOLUTEURL]}document/create/?" . self::relatedto2get([$related_to]), [
238
                            MIDCOM_TOOLBAR_LABEL => midcom::get()->i18n->get_string('create document', $data['component']),
239
                            MIDCOM_TOOLBAR_GLYPHICON => 'file-o',
240
                            MIDCOM_TOOLBAR_OPTIONS => ['data-refresh-opener' => 'true'],
241
                        ]);
242
                    }
243
                    break;
244
                default:
245
                    debug_add("given button '{$mode}' not recognized", MIDCOM_LOG_ERROR);
246
                    break;
247
            }
248
        }
249 5
        $toolbar->add_items($toolbar_buttons);
250
    }
251
252
    /**
253
     * function to add the button for journal_entry to the toolbar
254
     */
255 2
    public static function add_journal_entry_button(midcom_helper_toolbar $toolbar, string $guid)
256
    {
257 2
        $toolbar->add_item([
258 2
            MIDCOM_TOOLBAR_URL => "__mfa/org.openpsa.relatedto/journalentry/{$guid}/",
259 2
            MIDCOM_TOOLBAR_LABEL => midcom::get()->i18n->get_string('view journal entries', 'org.openpsa.relatedto'),
260 2
            MIDCOM_TOOLBAR_GLYPHICON => 'list',
261 2
        ]);
262
    }
263
}
264