Passed
Push — master ( c60b86...0ef755 )
by Andreas
17:33
created

org_openpsa_widgets_contact::show()   C

Complexity

Conditions 10
Paths 193

Size

Total Lines 61
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 15.123

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 34
c 1
b 0
f 0
nc 193
nop 0
dl 0
loc 61
ccs 22
cts 35
cp 0.6286
crap 15.123
rs 6.8916

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Class for rendering person records
4
 *
5
 * Uses the hCard microformat for output.
6
 *
7
 * @author Henri Bergius, http://bergie.iki.fi
8
 * @copyright Nemein Oy, http://www.nemein.com
9
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
10
 * @link http://www.microformats.org/wiki/hcard hCard microformat documentation
11
 * @package org.openpsa.widgets
12
 */
13
14
use midcom\datamanager\storage\blobs;
15
16
/**
17
 * @package org.openpsa.widgets
18
 */
19
class org_openpsa_widgets_contact extends midcom_baseclasses_components_purecode
20
{
21
    /**
22
     * Contact information of the person being displayed
23
     */
24
    public $contact_details = [
25
        'guid' => '',
26
        'id' => '',
27
        'firstname' => '',
28
        'lastname' => ''
29
    ];
30
31
    /**
32
     * Optional URI to person details
33
     *
34
     * @var string
35
     */
36
    public $link;
37
38
    /**
39
     * Optional HTML to be placed into the card
40
     *
41
     * @var string
42
     */
43
    public $extra_html;
44
45
    /**
46
     * Optional HTML to be placed into the card (before any other output in the DIV)
47
     *
48
     * @var string
49
     */
50
    public $prefix_html;
51
52
    /**
53
     * Whether to show person's groups in a list
54
     *
55
     * @var boolean
56
     */
57
    public $show_groups = true;
58
59
    /**
60
     * Whether to generate links to the groups using NAP
61
     *
62
     * @var boolean
63
     */
64
    var $link_contacts = true;
65
66
    /**
67
     * @var string
68
     */
69
    private static $_contacts_url;
70
71
    private $person;
72
73
    /**
74
     * Initializes the class and stores the selected person to be shown
75
     */
76 8
    public function __construct(midcom_db_person $person)
77
    {
78 8
        parent::__construct();
79
80 8
        if (null === self::$_contacts_url) {
0 ignored issues
show
introduced by
The condition null === self::_contacts_url is always false.
Loading history...
81 1
            $siteconfig = org_openpsa_core_siteconfig::get_instance();
82 1
            self::$_contacts_url = $siteconfig->get_node_full_url('org.openpsa.contacts');
83
        }
84
85
        // Read properties of provided person object
86
        // TODO: Handle groups as well
87 8
        $this->person = $person;
88 8
        $this->read_object($person);
89 8
    }
90
91 9
    public static function add_head_elements()
92
    {
93 9
        static $added = false;
94 9
        if (!$added) {
95 1
            midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . "/org.openpsa.widgets/hcard.css");
96 1
            midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/stock-icons/font-awesome-4.7.0/css/font-awesome.min.css');
97 1
            $added = true;
98
        }
99 9
    }
100
101
    /**
102
     * Retrieve an object, uses in-request caching
103
     *
104
     * @param mixed $src GUID of object (ids work but are discouraged)
105
     */
106 10
    public static function get($src) : self
107
    {
108 10
        static $cache = [];
109
110 10
        if (isset($cache[$src])) {
111 4
            return $cache[$src];
112
        }
113
114
        try {
115 7
            $person = midcom_db_person::get_cached($src);
116 1
        } catch (midcom_error $e) {
117 1
            return $cache[$src] = new self(new midcom_db_person);
118
        }
119
120 6
        $cache[$person->guid] = new self($person);
121 6
        $cache[$person->id] = $cache[$person->guid];
122 6
        return $cache[$person->guid];
123
    }
124
125
    /**
126
     * Read properties of a person object and populate local fields accordingly
127
     */
128 8
    private function read_object(midcom_db_person $person)
129
    {
130
        // Database identifiers
131 8
        $this->contact_details['guid'] = $person->guid;
132 8
        $this->contact_details['id'] = $person->id;
133
134 8
        if ($person->guid == "") {
135 1
            $this->contact_details['lastname'] = $this->_l10n->get('no person');
136 7
        } elseif ($person->firstname == '' && $person->lastname == '') {
137 7
            $this->contact_details['lastname'] = "Person #{$person->id}";
138
        } else {
139
            $this->contact_details['firstname'] = $person->firstname;
140
            $this->contact_details['lastname'] = $person->lastname;
141
        }
142
143 8
        foreach (['handphone', 'workphone', 'homephone', 'email', 'homepage'] as $property) {
144 8
            if ($person->$property) {
145
                $this->contact_details[$property] = $person->$property;
146
            }
147
        }
148
149 8
        if (   $this->_config->get('jabber_enable_presence')
150 8
            && $person->get_parameter('org.openpsa.jabber', 'jid')) {
151
            $this->contact_details['jid'] = $person->get_parameter('org.openpsa.jabber', 'jid');
152
        }
153
154 8
        if (   $this->_config->get('skype_enable_presence')
155 8
            && $person->get_parameter('org.openpsa.skype', 'name')) {
156
            $this->contact_details['skype'] = $person->get_parameter('org.openpsa.skype', 'name');
157
        }
158 8
    }
159
160 8
    private function _render_name(string $fallback_image) : string
161
    {
162 8
        $name = "<span class=\"given-name\">{$this->contact_details['firstname']}</span> <span class=\"family-name\">{$this->contact_details['lastname']}</span>";
163
164 8
        $url = false;
165
166 8
        if ($this->link) {
167
            $url = $this->link;
168 8
        } elseif ($this->link_contacts && !empty($this->contact_details['guid'])) {
169 8
            if (!self::$_contacts_url) {
170
                $this->link_contacts = false;
171
            } else {
172 8
                $url = self::$_contacts_url . 'person/' . $this->contact_details['guid'] . '/';
173
            }
174
        }
175
176 8
        $name = $this->get_image('thumbnail', $fallback_image) . $name;
177
178 8
        if ($url) {
179 8
            $name = '<a href="' . $url . '">' . $name . '</a>';
180
        }
181
182 8
        return $name;
183
    }
184
185 9
    public function get_image(string $type, string $fallback) : string
186
    {
187 9
        $attachments = blobs::get_attachments($this->person, 'photo');
188 9
        if (!empty($attachments[$type])) {
189
            return '<img class="photo" src="' . midcom_db_attachment::get_url($attachments[$type]) . '">';
190
        }
191 9
        if (   $this->_config->get('gravatar_enable')
192 9
            && !empty($this->contact_details['email'])) {
193
            $size = ($type == 'view') ? 500 : 32;
194
            $gravatar_url = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->contact_details['email']))) . "?s=" . $size . '&d=identicon';
195
            return "<img src=\"{$gravatar_url}\" class=\"photo\" />\n";
196
        }
197 9
        return '<i class="fa fa-' . $fallback . '"></i>';
198
    }
199
200
    /**
201
     * Show selected person object inline. Outputs hCard XHTML.
202
     */
203 9
    public function show_inline() : string
204
    {
205 9
        if (!$this->person->id) {
206 2
            return '';
207
        }
208 7
        self::add_head_elements();
209 7
        $inline_string = '';
210
211
        // Start the vCard
212 7
        $inline_string .= "<span class=\"vcard\">";
213
214 7
        if (!empty($this->contact_details['guid'])) {
215
            // Identifier
216 7
            $inline_string .= "<span class=\"uid\" style=\"display: none;\">{$this->contact_details['guid']}</span>";
217
        }
218
219
        // The name sequence
220 7
        $inline_string .= "<span class=\"n\">";
221 7
        $inline_string .= $this->_render_name('address-card-o');
222 7
        $inline_string .= "</span>";
223
224 7
        $inline_string .= "</span>";
225
226 7
        return $inline_string;
227
    }
228
229
    /**
230
     * Show the selected person. Outputs hCard XHTML.
231
     */
232 2
    public function show()
233
    {
234 2
        if (!$this->person->id) {
235
            return;
236
        }
237
238 2
        self::add_head_elements();
239
        // Start the vCard
240 2
        echo "<div class=\"vcard\" id=\"org_openpsa_widgets_contact-{$this->contact_details['guid']}\">\n";
241 2
        if ($this->prefix_html) {
242
            echo $this->prefix_html;
243
        }
244
245 2
        if (!empty($this->contact_details['guid'])) {
246
            // Identifier
247 2
            echo "<span class=\"uid\" style=\"display: none;\">{$this->contact_details['guid']}</span>";
248
        }
249
250
        // The Name sequence
251 2
        echo "<div class=\"n\">\n";
252 2
        echo $this->_render_name('user-o');
253 2
        echo "</div>\n";
254
255
        // Contact information sequence
256 2
        echo "<ul class=\"contact_information\">\n";
257 2
        if ($this->extra_html) {
258
            echo $this->extra_html;
259
        }
260
261 2
        $this->_show_groups();
262
263 2
        $this->_show_phone_number('handphone', 'mobile');
264 2
        $this->_show_phone_number('workphone', 'phone');
265 2
        $this->_show_phone_number('homephone', 'home');
266
267 2
        if (!empty($this->contact_details['email'])) {
268
            echo "<li><a title=\"{$this->contact_details['email']}\" href=\"mailto:{$this->contact_details['email']}\"><i class=\"fa fa-envelope-o\"></i>{$this->contact_details['email']}</a></li>\n";
269
        }
270
271 2
        if (!empty($this->contact_details['skype'])) {
272
            echo "<li>";
273
            echo "<a href=\"skype:{$this->contact_details['skype']}?call\"><i class=\"fa fa-skype\"></i>{$this->contact_details['skype']}</a></li>\n";
274
        }
275
276
        // Instant messaging contact information
277 2
        if (!empty($this->contact_details['jid'])) {
278
            echo "<li>";
279
            echo "<a href=\"xmpp:{$this->contact_details['jid']}\"";
280
            $edgar_url = $this->_config->get('jabber_edgar_url');
281
            if (!empty($edgar_url)) {
282
                echo " style=\"background-repeat: no-repeat;background-image: url('{$edgar_url}?jid={$this->contact_details['jid']}&type=image');\"";
283
            }
284
            echo "><i class=\"fa fa-comment-o\"></i>{$this->contact_details['jid']}</a></li>\n";
285
        }
286
287 2
        if (!empty($this->contact_details['homepage'])) {
288
            echo "<li><a title=\"{$this->contact_details['homepage']}\" href=\"{$this->contact_details['homepage']}\"><i class=\"fa fa-globe\"></i>{$this->contact_details['homepage']}</a></li>\n";
289
        }
290
291 2
        echo "</ul>\n";
292 2
        echo "</div>\n";
293 2
    }
294
295 2
    private function _show_phone_number(string $field, string $type)
296
    {
297 2
        if (!empty($this->contact_details[$field])) {
298
            echo "<li><a title=\"Dial {$this->contact_details[$field]}\" href=\"tel:{$this->contact_details[$field]}\"><i class=\"fa fa-{$type}\"></i>{$this->contact_details[$field]}</a></li>\n";
299
        }
300 2
    }
301
302 2
    private function _show_groups()
303
    {
304 2
        if (   !$this->show_groups
305 2
            || empty($this->contact_details['id'])) {
306
            return;
307
        }
308 2
        $link_contacts = $this->link_contacts && self::$_contacts_url;
309
310 2
        $mc = org_openpsa_contacts_member_dba::new_collector('uid', $this->contact_details['id']);
311 2
        $mc->add_constraint('gid.orgOpenpsaObtype', '>=', org_openpsa_contacts_group_dba::ORGANIZATION);
312
313 2
        foreach ($mc->get_rows(['gid', 'extra']) as $data) {
314
            try {
315
                $group = org_openpsa_contacts_group_dba::get_cached($data['gid']);
316
            } catch (midcom_error $e) {
317
                $e->log();
318
                continue;
319
            }
320
321
            echo "<li>";
322
323
            if ($data['extra']) {
324
                echo "<span class=\"title\">" . htmlspecialchars($data['extra']) . "</span>, ";
325
            }
326
327
            $group_label = htmlspecialchars($group->get_label());
0 ignored issues
show
Bug introduced by
The method get_label() does not exist on midcom_core_dbaobject. It seems like you code against a sub-type of midcom_core_dbaobject such as org_openpsa_calendar_event_dba or org_openpsa_invoices_invoice_dba or net_nemein_tag_tag_dba or org_openpsa_invoices_invoice_item_dba or midcom_db_parameter or org_openpsa_calendar_event_member_dba or org_openpsa_sales_salesproject_offer_dba or midcom_db_topic or net_nemein_tag_link_dba or org_openpsa_invoices_billing_data_dba or org_openpsa_directmarketing_campaign_member_dba or org_openpsa_contacts_group_dba or midcom_db_person or midcom_db_member or org_openpsa_projects_project or org_openpsa_calendar_event_resource_dba or midcom_db_group or org_openpsa_projects_task_dba or org_openpsa_documents_document_dba. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

327
            $group_label = htmlspecialchars($group->/** @scrutinizer ignore-call */ get_label());
Loading history...
328
            if ($link_contacts) {
329
                $group_label = "<a href=\"" . self::$_contacts_url . "group/{$group->guid}/\"><i class=\"fa fa-users\"></i>" . $group_label . '</a>';
330
            }
331
332
            echo "<span class=\"organization-name\">{$group_label}</span>";
333
            echo "</li>\n";
334
        }
335 2
    }
336
337
    /**
338
     * Renderer for organization address cards
339
     */
340 1
    public static function show_address_card($customer, array $cards)
341
    {
342 1
        $cards_to_show = [];
343 1
        $multiple_addresses = false;
344 1
        $inherited_cards_only = true;
345 1
        $default_shown = false;
346 1
        $siteconfig = org_openpsa_core_siteconfig::get_instance();
347 1
        $contacts_url = $siteconfig->get_node_full_url('org.openpsa.contacts');
348
349 1
        foreach ($cards as $cardname) {
350 1
            if ($cardname == 'visiting') {
351 1
                if ($customer->street) {
352
                    $default_shown = true;
353
                    $cards_to_show[] = $cardname;
354
                }
355 1
                continue;
356
            }
357
358 1
            $property = $cardname . 'Street';
359
360 1
            if (empty($cards_to_show)) {
361 1
                if ($customer->$property) {
362
                    $inherited_cards_only = false;
363
                    $cards_to_show[] = $cardname;
364 1
                } elseif (!$default_shown && $customer->street) {
365
                    $default_shown = true;
366 1
                    $cards_to_show[] = $cardname;
367
                }
368
            } elseif (    $customer->$property
369
                      || ($customer->street && !$inherited_cards_only && !$default_shown)) {
370
                $inherited_cards_only = false;
371
                $multiple_addresses = true;
372
                $cards_to_show[] = $cardname;
373
            }
374
        }
375
376 1
        if (empty($cards_to_show)) {
377 1
            return;
378
        }
379
380
        $root_group = org_openpsa_contacts_interface::find_root_group();
381
        $parent = $customer->get_parent();
382
        $parent_name = false;
383
        if ($parent->id != $root_group->id) {
384
            $parent_name = $parent->get_label();
385
        }
386
387
        foreach ($cards_to_show as $cardname) {
388
            echo '<div class="vcard">';
389
            if (   $multiple_addresses
390
                || (   $cardname != 'visiting'
391
                    && !$inherited_cards_only)) {
392
                echo '<div style="text-align:center"><em>' . midcom::get()->i18n->get_string($cardname . ' address', 'org.openpsa.contacts') . "</em></div>\n";
393
            }
394
            echo "<strong>\n";
395
            if ($parent_name) {
396
                echo '<a href="' . $contacts_url . 'group/' . $parent->guid . '/">' . $parent_name . "</a><br />\n";
0 ignored issues
show
Bug introduced by
Are you sure $contacts_url of type false|mixed|null can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

396
                echo '<a href="' . /** @scrutinizer ignore-type */ $contacts_url . 'group/' . $parent->guid . '/">' . $parent_name . "</a><br />\n";
Loading history...
397
            }
398
399
            $label = $customer->get_label();
400
401
            if ($cardname != 'visiting') {
402
                $label_property = $cardname . '_label';
403
                $label = $customer->$label_property;
404
            }
405
406
            echo $label . "\n";
407
            echo "</strong>\n";
408
409
            $property_street = 'street';
410
            $property_postcode = 'postcode';
411
            $property_city = 'city';
412
413
            if ($cardname != 'visiting') {
414
                $property_street = $cardname . 'Street';
415
                $property_postcode = $cardname . 'Postcode';
416
                $property_city = $cardname . 'City';
417
            }
418
            if ($customer->$property_street) {
419
                echo "<p>{$customer->$property_street}<br />\n";
420
                echo "{$customer->$property_postcode} {$customer->$property_city}</p>\n";
421
            } elseif ($customer->street) {
422
                echo "<p>{$customer->street}<br />\n";
423
                echo "{$customer->postcode} {$customer->city}</p>\n";
424
            }
425
            echo "</div>\n";
426
        }
427
    }
428
}
429