Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 360
0.00% covered (danger)
0.00%
0 / 21
CRAP
0.00% covered (danger)
0.00%
0 / 3
zeroBSCRM_TasksMetaboxSetup
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
zeroBSCRM_task_addEdit
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
72
zeroBSCRM_task_ui_clear
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
zeroBSCRM_task_ui_assignment
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
72
jpcrm_task_ui_mark_complete
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
20
zeroBSCRM_task_ui_for
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
90
zeroBSCRM_task_ui_for_co
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
132
jpcrm_task_ui_daterange
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
zeroBSCRM_task_ui_reminders
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
90
zeroBSCRM_task_ui_showOnCalendar
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
42
zeroBSCRM_task_ui_showOnPortal
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
zeroBSCRM_task_ui_comments
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
zeroBSCRM_task_ui_description
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
zeroBS__Metabox_Task
0.00% covered (danger)
0.00%
0 / 101
0.00% covered (danger)
0.00%
0 / 5
1190
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 html
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 save_data
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 1
600
 post_save_data
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 updateMessage
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
zeroBS__Metabox_TaskActions
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 2
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 html
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
30
zeroBS__Metabox_TaskTags
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/*
3 * Jetpack CRM
4 * https://jetpackcrm.com
5 * V3.0
6 *
7 * Copyright 2020 Automattic
8 *
9 * Date: 20/02/2019
10 */
11
12/*
13======================================================
14    Breaking Checks ( stops direct access )
15    ====================================================== */
16if ( ! defined( 'ZEROBSCRM_PATH' ) ) {
17    exit( 0 );
18}
19/*
20======================================================
21    / Breaking Checks
22    ====================================================== */
23
24/*
25======================================================
26    Init Func
27    ====================================================== */
28
29function zeroBSCRM_TasksMetaboxSetup() {
30
31    $zeroBS__Metabox_Task = new zeroBS__Metabox_Task( __FILE__ );
32
33    // actions box
34    $zeroBS__Metabox_TaskActions = new zeroBS__Metabox_TaskActions( __FILE__ );
35
36    // tags
37    $zeroBS__Metabox_TaskTags = new zeroBS__Metabox_TaskTags( __FILE__ );
38}
39
40    add_action( 'admin_init', 'zeroBSCRM_TasksMetaboxSetup' );
41
42/*
43======================================================
44    / Init Func
45    ====================================================== */
46
47/*
48======================================================
49    Task Metabox
50    ====================================================== */
51
52class zeroBS__Metabox_Task extends zeroBS__Metabox {
53
54    // this is for catching 'new' task
55    private $newRecordNeedsRedir = false;
56
57    public function __construct( $plugin_file ) {
58
59        // set these
60        // DAL3 switched for objType $this->postType = 'zerobs_customer';
61        $this->objType         = 'event';
62        $this->metaboxID       = 'jpcrm-task-edit';
63        $this->metaboxTitle    = __( 'Task Information', 'zero-bs-crm' );
64        $this->metaboxScreen   = 'zbs-add-edit-event-edit';
65        $this->metaboxArea     = 'normal';
66        $this->metaboxLocation = 'high';
67        $this->saveOrder       = 1;
68        $this->capabilities    = array(
69
70            'can_hide'        => false, // can be hidden
71            'areas'           => array( 'normal' ), // areas can be dragged to - normal side = only areas currently
72            'can_accept_tabs' => true,  // can/can't accept tabs onto it
73            'can_become_tab'  => false, // can be added as tab
74            'can_minimise'    => true, // can be minimised
75            'can_move'        => true, // can be moved
76
77        );
78
79        // call this
80        $this->initMetabox();
81    }
82
83    public function html( $task, $metabox ) {
84
85            // localise ID
86            $task_id = -1;
87        if ( is_array( $task ) && isset( $task['id'] ) ) {
88            $task_id = (int) $task['id'];
89        }
90
91            // debug echo 'task:<pre>'; print_r(array($task,$metabox)); echo '</pre>';
92
93            // PerfTest: zeroBSCRM_performanceTest_startTimer('custmetabox-dataget');
94
95            #} Rather than reload all the time :)
96            global $zbsTaskEditing;
97
98            // PerfTest: zeroBSCRM_performanceTest_finishTimer('custmetabox-dataget');
99            // PerfTest: zeroBSCRM_performanceTest_startTimer('custmetabox-draw'); ?>
100
101                <script type="text/javascript">var zbscrmjs_secToken = '<?php echo esc_js( wp_create_nonce( 'zbscrmjs-ajax-nonce' ) ); ?>';</script>
102
103                <?php
104                #} Pass this if it's a new customer (for internal automator) - note added this above with DEFINE for simpler.
105
106                if ( gettype( $task ) != 'array' ) {
107                    echo '<input type="hidden" name="zbscrm_newevent" value="1" />';
108                }
109
110                // MS HTML out..
111                // from the function lower down in this file.
112                echo zeroBSCRM_task_addEdit( $task_id );
113
114                // PerfTest: zeroBSCRM_performanceTest_finishTimer('custmetabox-draw');
115    }
116
117    public function save_data( $task_id, $task ) {
118
119        if ( ! defined( 'ZBS_OBJ_SAVED' ) ) {
120
121            // debug if (get_current_user_id() == 12) echo 'FIRING<br>';
122
123            define( 'ZBS_OBJ_SAVED', 1 );
124
125            // DAL3.0+
126            global $zbs;
127
128            // check this
129            if ( empty( $task_id ) || $task_id < 1 ) {
130                $task_id = -1;
131            }
132
133            // DAL3 way:
134            $autoGenAutonumbers = true; // generate if not set :)
135            $task               = zeroBS_buildObjArr( $_POST, array(), 'zbse_', '', false, ZBS_TYPE_TASK, $autoGenAutonumbers );
136
137            // catch calendar and portal options (show_on_portal not needed)
138            $task['show_on_cal'] = -1;
139            if ( isset( $_POST['zbse_show_on_cal'] ) ) {
140                $task['show_on_cal'] = 1;
141            }
142
143            // Use the tag-class function to retrieve any tags so we can add inline.
144            // Save tags against objid
145            $task['tags'] = zeroBSCRM_tags_retrieveFromPostBag( true, ZBS_TYPE_TASK );
146
147            // because we deal with non-model datetime stamps here, we have to process separate to buildObjArr:
148
149            // jpcrm_datetime_post_keys_to_uts() sanitises POST data
150            $task_start = jpcrm_datetime_post_keys_to_uts( 'jpcrm_start' );
151            $task_end   = jpcrm_datetime_post_keys_to_uts( 'jpcrm_end' );
152
153            // if unable to use task start input, set to current time
154            if ( ! $task_start ) {
155                // start +1 hour from now
156                $task_start = time() + 3600;
157
158                // round to 15 minutes
159                $task_start -= $task_start % 900;
160            }
161
162            if ( ! $task_end || $task_end < $task_start ) {
163                // set to task start time + 1 hour if end is not set or is before start
164                $task_end = $task_start + 3600;
165            }
166
167            $task['start'] = $task_start;
168            $task['end']   = $task_end;
169
170            // obj links:
171            $task['contacts'] = array();
172            if ( isset( $_POST['zbse_customer'] ) ) {
173                $task['contacts'][] = (int) sanitize_text_field( $_POST['zbse_customer'] );
174            }
175            $task['companies'] = array();
176            if ( isset( $_POST['zbse_company'] ) ) {
177                $task['companies'][] = (int) sanitize_text_field( $_POST['zbse_company'] );
178            }
179
180            // completeness:
181            $task['complete'] = -1;
182            if ( isset( $_POST['zbs-task-complete'] ) ) {
183                $task['complete'] = (int) sanitize_text_field( $_POST['zbs-task-complete'] );
184            }
185
186            $zbs->DAL->events->setEventCompleteness( $task_id, $task['complete'] );
187
188            // ownership also passed via post here.
189            $owner = -1;
190            if ( isset( $_POST['zbse_owner'] ) ) {
191
192                // this could do with some CHECK to say "can this user assign to this (potentially other) user"
193                $owner = (int) sanitize_text_field( $_POST['zbse_owner'] );
194
195            }
196
197            // get old-style notify -> reminders
198            $task_reminders    = array();
199            $jpcrm_task_notify = false;
200            if ( isset( $_POST['zbs_remind_task_24'] ) ) {
201                $jpcrm_task_notify = (int) sanitize_text_field( $_POST['zbs_remind_task_24'] );
202            }
203            if ( $jpcrm_task_notify > 0 ) {
204
205                    // this was only ever 0 or 24
206                if ( $jpcrm_task_notify == 24 ) {
207                    $task_reminders[] = array(
208
209                        'remind_at' => -86400,
210                        'sent'      => -1,
211
212                    );
213                }
214            }
215            $task['reminders'] = $task_reminders;
216
217            // add/update
218            $addUpdateReturn = $zbs->DAL->events->addUpdateEvent(
219                array(
220
221                    'id'            => $task_id,
222                    'owner'         => $owner,
223                    'data'          => $task,
224                    'limitedFields' => -1,
225
226                )
227            );
228
229            // Note: For NEW objs, we make sure a global is set here, that other update funcs can catch
230            // ... so it's essential this one runs first!
231            // this is managed in the metabox Class :)
232            if ( $task_id == -1 && ! empty( $addUpdateReturn ) && $addUpdateReturn != -1 ) {
233
234                $task_id = $addUpdateReturn;
235                global $zbsJustInsertedMetaboxID;
236                $zbsJustInsertedMetaboxID = $task_id;
237
238                // set this so it redirs
239                $this->newRecordNeedsRedir = true;
240            }
241
242            // success?
243            if ( $addUpdateReturn != -1 && $addUpdateReturn > 0 ) {
244
245                // Update Msg
246                // this adds an update message which'll go out ahead of any content
247                // This adds to metabox: $this->updateMessages['update'] = zeroBSCRM_UI2_messageHTML('info olive mini zbs-not-urgent',__('Contact Updated',"zero-bs-crm"),'','address book outline','contactUpdated');
248                // This adds to edit page
249                $this->updateMessage();
250
251                // catch any non-critical messages
252                $nonCriticalMessages = $zbs->DAL->getErrors( ZBS_TYPE_TASK );
253                if ( is_array( $nonCriticalMessages ) && count( $nonCriticalMessages ) > 0 ) {
254                    $this->dalNoticeMessage( $nonCriticalMessages );
255                }
256            } else {
257
258                // fail somehow
259                $failMessages = $zbs->DAL->getErrors( ZBS_TYPE_TASK );
260
261                // show msg (retrieved from DAL err stack)
262                if ( is_array( $failMessages ) && count( $failMessages ) > 0 ) {
263                    $this->dalErrorMessage( $failMessages );
264                } else {
265                    $this->dalErrorMessage( array( __( 'Insert/Update Failed with general error', 'zero-bs-crm' ) ) );
266                }
267
268                // pass the pre-fill:
269                global $zbsObjDataPrefill;
270                $zbsObjDataPrefill = $task;
271
272            }
273        }
274
275        return $task;
276    }
277
278    // This catches 'new' contacts + redirs to right url
279    public function post_save_data( $objID, $obj ) {
280
281        if ( $this->newRecordNeedsRedir ) {
282
283            global $zbsJustInsertedMetaboxID;
284            if ( ! empty( $zbsJustInsertedMetaboxID ) && $zbsJustInsertedMetaboxID > 0 ) {
285
286                // redir
287                wp_redirect( jpcrm_esc_link( 'edit', $zbsJustInsertedMetaboxID, $this->objType ) );
288                exit( 0 );
289
290            }
291        }
292    }
293
294    public function updateMessage() {
295
296        global $zbs;
297
298        // zbs-not-urgent means it'll auto hide after 1.5s
299        // genericified from DAL3.0
300        $msg = zeroBSCRM_UI2_messageHTML( 'info olive mini zbs-not-urgent', $zbs->DAL->typeStr( $zbs->DAL->objTypeKey( $this->objType ) ) . ' ' . __( 'Updated', 'zero-bs-crm' ), '', 'address book outline', 'contactUpdated' );
301
302        $zbs->pageMessages[] = $msg;
303    }
304}
305
306/*
307======================================================
308    / Task Metabox
309    ====================================================== */
310
311/*
312======================================================
313    Task Actions Metabox
314    ====================================================== */
315
316class zeroBS__Metabox_TaskActions extends zeroBS__Metabox {
317
318    public function __construct( $plugin_file ) {
319
320        // set these
321        $this->objType         = 'event';
322        $this->metaboxID       = 'zerobs-event-actions';
323        $this->metaboxTitle    = __( 'Task Actions', 'zero-bs-crm' ); // will be headless anyhow
324        $this->headless        = true;
325        $this->metaboxScreen   = 'zbs-add-edit-event-edit';
326        $this->metaboxArea     = 'side';
327        $this->metaboxLocation = 'high';
328        $this->saveOrder       = 1;
329        $this->capabilities    = array(
330
331            'can_hide'        => false, // can be hidden
332            'areas'           => array( 'high' ), // areas can be dragged to - normal side = only areas currently
333            'can_accept_tabs' => true,  // can/can't accept tabs onto it
334            'can_become_tab'  => false, // can be added as tab
335            'can_minimise'    => true, // can be minimised
336            'can_move'        => true, // can be moved
337
338        );
339
340        // call this
341        $this->initMetabox();
342    }
343
344    public function html( $task, $metabox ) {
345
346        ?>
347            <div class="zbs-generic-save-wrap">
348
349                <div class="ui medium dividing header"><i class="save icon"></i> <?php esc_html_e( 'Task Actions', 'zero-bs-crm' ); ?></div>
350
351            <?php
352
353            // localise ID & content
354            $task_id = -1;
355            if ( is_array( $task ) && isset( $task['id'] ) ) {
356                $task_id = (int) $task['id'];
357            }
358
359            if ( $task_id > 0 ) {
360                ?>
361
362                    <div class="zbs-task-actions-bottom zbs-objedit-actions-bottom">
363
364                            <button class="ui button black" type="button" id="zbs-edit-save"><?php esc_html_e( 'Update', 'zero-bs-crm' ); ?> <?php esc_html_e( 'Task', 'zero-bs-crm' ); ?></button>
365
366                        <?php
367
368                            // delete?
369
370                        // for now just check if can modify, later better, granular perms.
371                        if ( zeroBSCRM_perms_tasks() ) {
372                            ?>
373                        <div id="zbs-task-actions-delete" class="zbs-objedit-actions-delete">
374                            <a class="submitdelete deletion" href="<?php echo jpcrm_esc_link( 'delete', $task_id, 'event' ); ?>"><?php esc_html_e( 'Delete Permanently', 'zero-bs-crm' ); ?></a>
375                        </div>
376                        <?php } // can delete ?>
377                        
378                        <div class='clear'></div>
379
380                    </div>
381                <?php
382
383            } else {
384
385                    // NEW Task
386                ?>
387
388                        <button class="ui button black" type="button" id="zbs-edit-save"><?php esc_html_e( 'Save', 'zero-bs-crm' ); ?> <?php esc_html_e( 'Task', 'zero-bs-crm' ); ?></button>
389
390                <?php
391
392            }
393
394            ?>
395            </div>
396            <?php
397            // / .zbs-generic-save-wrap
398    } // html
399
400    // saved via main metabox
401}
402
403/*
404======================================================
405    / Tasks Actions Metabox
406    ====================================================== */
407
408/*
409======================================================
410    Create Tags Box
411    ====================================================== */
412
413class zeroBS__Metabox_TaskTags extends zeroBS__Metabox_Tags {
414
415    public function __construct( $plugin_file ) {
416
417        $this->objTypeID = ZBS_TYPE_TASK;
418        // DAL3 switched for objType $this->postType = 'zerobs_customer';
419        $this->objType         = 'event';
420        $this->metaboxID       = 'zerobs-event-tags';
421        $this->metaboxTitle    = __( 'Task Tags', 'zero-bs-crm' );
422        $this->metaboxScreen   = 'zbs-add-edit-event-edit'; // 'zerobs_edit_contact'; // we can use anything here as is now using our func
423        $this->metaboxArea     = 'side';
424        $this->metaboxLocation = 'low';
425        $this->showSuggestions = true;
426        $this->capabilities    = array(
427
428            'can_hide'        => true, // can be hidden
429            'areas'           => array( 'side' ), // areas can be dragged to - normal side = only areas currently
430            'can_accept_tabs' => false,  // can/can't accept tabs onto it
431            'can_become_tab'  => false, // can be added as tab
432            'can_minimise'    => true, // can be minimised
433
434        );
435
436        // call this
437        $this->initMetabox();
438    }
439
440    // html + save dealt with by parent class :)
441}
442
443/*
444======================================================
445    / Create Tags Box
446    ====================================================== */
447
448/*
449======================================================
450    Task UI code - outputting the HTML for the task
451    ====================================================== */
452
453function zeroBSCRM_task_addEdit( $taskID = -1 ) {
454
455    global $zbs;
456
457    $taskObject = $zbs->DAL->events->getEvent(
458        $taskID,
459        array(
460            'withReminders'    => true,
461            'withCustomFields' => true,
462            'withTags'         => false,
463            'withOwner'        => false,
464        )
465    );
466
467    // catch fresh/new?
468    if ( ! is_array( $taskObject ) ) {
469        $taskObject = array();
470    }
471
472    /*
473    $uid = get_current_user_id();
474    $zbsThisOwner = zeroBS_getOwner($taskID,true,'zerobs_event');
475    ... this'd just be $taskObject['owner'] 3.0 + :)
476
477    if($uid != $zbsThisOwner['ID']){
478
479        $html = "<div class='ui segment'>";
480        $html .= __("You cannot edit this task. It is not your task. Ask the task owner to modify.", 'zero-bs-crm');
481
482    }else{ */
483
484    if ( $taskID > 0 ) {
485        $html = "<div id='task-" . $taskID . "' class='jpcrm-task-editor-wrap'>";
486    } else {
487        $html = "<div id='task-0' class='jpcrm-task-editor-wrap'>";
488    }
489
490    $html .= zeroBSCRM_task_ui_clear();
491
492    $title = '';
493    if ( is_array( $taskObject ) && isset( $taskObject['title'] ) ) {
494        $title = $taskObject['title'];
495    }
496    $placeholder = __( 'Task Name...', 'zero-bs-crm' );
497    if ( is_array( $taskObject ) && isset( $taskObject['placeholder'] ) ) {
498        $placeholder = $taskObject['placeholder'];
499    }
500    // WH: Not sure placeholder is really req 3.0? What was that even? (It's not a field we've added to the data model)
501
502    $html .= '<div id="zbs-task-title-row">';
503    $html .= "<input id='zbs-task-title' name='zbse_title' type='text' value='" . esc_attr( $title ) . "' placeholder='" . $placeholder . "' />";
504    $html .= jpcrm_task_ui_mark_complete( $taskObject ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
505    $html .= '</div>';
506
507    $html .= zeroBSCRM_task_ui_clear();
508
509    $html .= jpcrm_task_ui_daterange( $taskObject ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
510
511    $html .= zeroBSCRM_task_ui_clear();
512
513    $html .= zeroBSCRM_task_ui_assignment( $taskObject, $taskID ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
514
515    $html .= zeroBSCRM_task_ui_clear();
516
517    $html .= zeroBSCRM_task_ui_description( $taskObject );
518
519    $html .= zeroBSCRM_task_ui_clear();
520
521    $html .= zeroBSCRM_task_ui_reminders( $taskObject, $taskID );
522
523    $html .= zeroBSCRM_task_ui_clear();
524
525    // NOTE show_on_portal is available and could clone this v3.0+
526    $html .= zeroBSCRM_task_ui_showOnCalendar( $taskObject, $taskID );
527
528    $html .= zeroBSCRM_task_ui_clear();
529
530    if ( class_exists( 'ZeroBSCRM_ClientPortalPro' ) ) {
531        $html .= zeroBSCRM_task_ui_showOnPortal( $taskObject );
532    }
533
534    $html .= zeroBSCRM_task_ui_clear();
535
536    $html .= zeroBSCRM_task_ui_for( $taskObject ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
537
538    $html .= zeroBSCRM_task_ui_clear();
539
540    $html .= zeroBSCRM_task_ui_for_co( $taskObject );
541
542    $html .= '</div>';
543
544    return $html;
545}
546
547function zeroBSCRM_task_ui_clear() {
548    return '<div class="clear zbs-task-clear"></div>'; }
549
550#} Assign to CRM user UI
551function zeroBSCRM_task_ui_assignment( $taskObject = array(), $taskID = -1 ) {
552
553    global $zbs;
554
555    $current_task_user_id = -1;
556    if ( array_key_exists( 'owner', $taskObject ) ) {
557        $current_task_user_id = $taskObject['owner'];
558    }
559
560    $html = '';
561    if ( $current_task_user_id === '' || $current_task_user_id <= 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
562
563        $html .= "<div class='jpcrm-task-owner'><i class='ui icon user circle zbs-unassigned'></i>";
564
565    } else {
566
567        $owner_info   = get_userdata( $current_task_user_id );
568        $display_name = $owner_info->data->display_name;
569        $ava_args     = array(
570            'class' => 'rounded-circle',
571        );
572        $avatar       = jpcrm_get_avatar( $current_task_user_id, 30, '', $display_name, $ava_args );
573        $html        .= '<div class="jpcrm-task-owner">' . $avatar;
574
575    }
576
577    $uid        = get_current_user_id();
578    $linked_cal = $zbs->DAL->meta( ZBS_TYPE_TASK, $taskID, $key = 'zbs_outlook_id', false ); // false = default here
579
580    if ( $uid != $current_task_user_id ) {
581        // then it is LOCKED and cannot be changed to another owner?
582    }
583
584    // get potential owners
585    $jpcrm_tasks_users = zeroBS_getPossibleTaskOwners();
586
587    $html .= '<select id="zerobscrm-owner" name="zbse_owner">';
588    $html .= '<option value="-1">' . __( 'None', 'zero-bs-crm' ) . '</option>';
589
590    if ( count( $jpcrm_tasks_users ) > 0 ) {
591        foreach ( $jpcrm_tasks_users as $possOwner ) {
592            $html .= '<option value="' . $possOwner->ID . '"';
593            if ( $possOwner->ID == $current_task_user_id ) {
594                $html .= ' selected="selected"';
595            }
596            $html .= '>' . esc_html( $possOwner->display_name ) . '</option>';
597        }
598    }
599    $html .= '</select></div>';
600
601    return $html;
602}
603
604/**
605 * Generates HTML for the task status buttons.
606 *
607 * @param array $task_object Task object.
608 */
609function jpcrm_task_ui_mark_complete( $task_object = array() ) {
610    $html = '<div id="mark-complete-task">';
611
612    if ( ! array_key_exists( 'complete', $task_object ) ) {
613        $task_object['complete'] = -1;
614    }
615    $html .= sprintf(
616        '<button type="button" class="ui button black%s" data-status="1"><i class="ui icon check green"></i>%s</button>',
617        $task_object['complete'] !== 1 ? ' hidden' : '',
618        __( 'Completed', 'zero-bs-crm' )
619    );
620    $html .= sprintf(
621        '<button type="button" class="ui button white%s" data-status="-1">%s</button>',
622        $task_object['complete'] === 1 ? ' hidden' : '',
623        __( 'Mark Complete', 'zero-bs-crm' )
624    );
625    $html .= '<input type="hidden" id="zbs-task-complete" value="' . $task_object['complete'] . '" name="zbs-task-complete" />';
626
627    $html .= '</div>';
628
629    return $html;
630}
631
632#} CRM company / contact assignment
633#} assign to CRM user UI
634function zeroBSCRM_task_ui_for( $taskObject = array() ) {
635    global $zbs;
636    $html = "<div class='no-contact zbs-task-for-who'><div class='zbs-task-for-help'><i class='ui icon users'></i> " . __( 'Contact', 'zero-bs-crm' ) . '</div>';
637
638    // need UI for selecting who the task is for (company, then contaxt)
639    $custName = '';
640    $custID   = '';
641
642    if ( isset( $taskObject['contact'] ) && is_array( $taskObject['contact'] ) ) {
643
644        $taskContact = $taskObject['contact'];
645
646        // for now this needs a 0 offset as has potential for multi-contact
647        if ( isset( $taskContact[0] ) && is_array( $taskContact[0] ) ) {
648
649            $taskContact = $taskContact[0];
650        }
651
652        if ( isset( $taskContact['id'] ) ) {
653            $custID = $taskContact['id'];
654        }
655        $custName = $zbs->DAL->contacts->getContactNameWithFallback( $custID );
656    } elseif ( isset( $_GET['zbsprefillcust'] ) && ! empty( $_GET['zbsprefillcust'] ) ) {
657        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
658            $custID   = (int) $_GET['zbsprefillcust'];
659            $custName = $zbs->DAL->contacts->getContactNameWithFallback( $custID );
660    }
661
662    #} Output
663    $html .= '<div class="zbs-task-for">' . zeroBSCRM_CustomerTypeList( 'jpcrm_tasks_setContact', $custName, true, 'jpcrm_tasks_changeContact' ) . '</div>'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
664    $html .= '<input type="hidden" name="zbse_customer" id="zbse_customer" value="' . ( $custName ? $custID : '' ) . '" />'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
665    $html .= '<div class="clear"></div></div>';
666
667    return $html;
668}
669
670function zeroBSCRM_task_ui_for_co( $taskObject = array() ) {
671    global $zbs;
672    $html = '';
673
674    if ( zeroBSCRM_getSetting( 'companylevelcustomers' ) == '1' ) {
675
676        $html .= "<div class='no-contact zbs-task-for-who'><div class='zbs-task-for-help'><i class='ui icon building outline'></i> " . jpcrm_label_company() . '</div>';
677
678        // need UI for selecting who the task is for (company, then contact)
679        $co_name = '';
680        $co_id   = '';
681
682        if ( isset( $taskObject['company'] ) && is_array( $taskObject['company'] ) ) {
683
684            $task_company = $taskObject['company']; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
685
686            // for now this needs a 0 offset as has potential for multi-contact
687            if ( isset( $task_company[0] ) && is_array( $task_company[0] ) ) {
688                $task_company = $task_company[0];
689            }
690
691            if ( isset( $task_company['id'] ) ) {
692                $co_id = $task_company['id'];
693            }
694            if ( isset( $task_company['name'] ) ) {
695                $co_name = $task_company['name'];
696            }
697        } elseif ( isset( $_GET['zbsprefillco'] ) && ! empty( $_GET['zbsprefillco'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
698                $co_id   = (int) $_GET['zbsprefillco']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
699                $co_name = $zbs->DAL->companies->getCompanyNameEtc( $co_id ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
700        }
701
702        #} Output
703        $html .= '<div class="zbs-task-for-company">' . zeroBSCRM_CompanyTypeList( 'jpcrm_tasks_setCompany', $co_name, true, 'jpcrm_tasks_changeCompany' ) . '</div>';
704        $html .= '<input type="hidden" name="zbse_company" id="zbse_company" value="' . ( $co_name ? $co_id : '' ) . '" />';
705        $html .= '<div class="clear"></div></div>';
706
707    }
708
709    return $html;
710}
711
712/**
713 * Returns a string for disabling browser autocomplete
714 * Ideally we'd just use "off", but support is not complete: https://caniuse.com/input-autocomplete-onoff
715 *
716 * @param array $task_object Object containing task details.
717 *
718 * @return string $html Contains the start/end date and time inputs.
719 */
720function jpcrm_task_ui_daterange( $task_object = array() ) {
721
722    if ( ! isset( $task_object['start'] ) ) {
723
724        // no task start defined yet, so use some defaults
725
726        // start +1 hour from now
727        $task_start = time() + 3600;
728
729        // round to 15 minutes
730        $task_start -= $task_start % 900;
731
732        // end +1 hour from start
733        $task_end = $task_start + 3600;
734
735    } else {
736
737        $task_start = $task_object['start'];
738        $task_end   = $task_object['end'];
739
740    }
741
742    // For now, hack together a table so the date and time inputs line up nicely. Eventually we'll want to rework the entire UI of this page.
743    $html = '
744<table style="margin-left:20px;">
745    <tr class="jpcrm-task-time">
746        <td><label>' . esc_html__( 'Start time', 'zero-bs-crm' ) . ':</label>&nbsp;</td>
747        <td>
748            <input type="date" name="jpcrm_start_datepart" value="' . esc_attr( jpcrm_uts_to_date_str( $task_start, 'Y-m-d' ) ) . '" autocomplete="' . esc_attr( jpcrm_disable_browser_autocomplete() ) . '" />
749            @ 
750            <input type="time" name="jpcrm_start_timepart" value="' . esc_attr( jpcrm_uts_to_date_str( $task_start, 'H:i' ) ) . '" autocomplete="' . esc_attr( jpcrm_disable_browser_autocomplete() ) . '" />
751        </td>
752    </tr>
753    <tr class="jpcrm-task-time">
754        <td><label>' . esc_html__( 'End time', 'zero-bs-crm' ) . ':</label>&nbsp;</td>
755        <td>
756            <input type="date" name="jpcrm_end_datepart" value="' . esc_attr( jpcrm_uts_to_date_str( $task_end, 'Y-m-d' ) ) . '" autocomplete="' . esc_attr( jpcrm_disable_browser_autocomplete() ) . '" />
757            @ 
758            <input type="time" name="jpcrm_end_timepart" value="' . esc_attr( jpcrm_uts_to_date_str( $task_end, 'H:i' ) ) . '" autocomplete="' . esc_attr( jpcrm_disable_browser_autocomplete() ) . '" />
759        </td>
760    </tr>
761</table>';
762
763    return $html;
764}
765
766#} UI Reminders
767function zeroBSCRM_task_ui_reminders( $taskObject = array(), $taskID = -1 ) {
768
769    $show = false;
770
771    // v3.0 + this is differently stored:
772    // if (isset($taskObject['notify_crm'])) $show = $taskObject['notify_crm'];
773    if ( isset( $taskObject['reminders'] ) && is_array( $taskObject['reminders'] ) ) {
774
775        // eventually diff time reminders will be in this array, for v3.0 we only have 24h reminders
776        foreach ( $taskObject['reminders'] as $reminder ) {
777
778            if ( is_array( $reminder ) && isset( $reminder['remind_at'] ) ) {
779
780                // catch 24
781                if ( $reminder['remind_at'] == -86400 ) {
782                    $show = true;
783                }
784            }
785        }
786    } else {
787
788        // new, set default:
789        $show = true;
790    }
791
792    $html      = "<div class='remind_task'>";
793        $html .= '<div>';
794
795            // add admin cog (settings) for task notification template
796    if ( zeroBSCRM_isZBSAdminOrAdmin() ) {
797            $html .= sprintf(
798                '<a href="%s" class="button button-primary button-large" style="background-color:black;border-color:black;" title="%s" target="_blank"><i class="cogs icon"></i></a>',
799                esc_url_raw( jpcrm_esc_link( 'zbs-email-templates' ) . '&zbs_template_id=' . ZBSEMAIL_TASK_NOTIFICATION ),
800                __( 'Admin: Notification Settings', 'zero-bs-crm' )
801            );
802    }
803
804        $html .= '<input name="zbs_remind_task_24" id="zbs_remind_task_24" type="checkbox" value="24"';
805    if ( $show ) {
806        $html .= ' checked="checked"';
807    }
808        $html .= "/><label for='zbs_remind_task_24'>" . __( 'Remind CRM member 24 hours before', 'zero-bs-crm' ) . '</label></div>';
809    // $html .= "<a class='ui label blue' href='". admin_url('admin.php?page=zbs-reminders') ."' target='_blank' style='margin-top: 0.2em;margin-right: 0.3em;'>" .__('Add more reminders', 'zero-bs-crm') . "</a>";
810    $html .= '</div>';
811
812    #} Better reminders in Calendar Pro :-)
813    $html = apply_filters( 'zbs_task_reminders', $html );
814
815    return $html;
816}
817
818// NOTE show_on_portal is available and could clone this v3.0+
819function zeroBSCRM_task_ui_showOnCalendar( $taskObject = array(), $taskID = -1 ) {
820
821    global $zbs;
822
823    // show?
824    $show = false;
825    if ( isset( $taskObject['show_on_cal'] ) ) {
826        if ( $taskObject['show_on_cal'] == 1 ) {
827            $show = true;
828        }
829    } else {
830        // new, set default:
831        $show = true;
832    }
833
834    $linked_cal = $zbs->DAL->meta( ZBS_TYPE_TASK, $taskID, $key = 'zbs_outlook_id', false ); // false = default here
835
836    $html = "<div class='show-on-calendar'>";
837    if ( $linked_cal != '' ) {
838        $html .= '<div class="zbs-hide"><input name="zbse_show_on_cal" id="zbse_show_on_cal" type="checkbox" value="1"';
839        if ( $show ) {
840            $html .= ' checked="checked"';
841        }
842        $html .= "/></div><div class='outlook-event'>" . __( 'Linked to Online Calendar (will always show on CRM Calendar)', 'zero-bs-crm' ) . '</div>';
843    } else {
844        $html .= '<div><input name="zbse_show_on_cal" id="zbse_show_on_cal" type="checkbox" value="1"';
845        if ( $show ) {
846            $html .= ' checked="checked"';
847        }
848        $html .= "/><label for='zbse_show_on_cal'>" . __( 'Show on Calendar', 'zero-bs-crm' ) . '</label></div></div>';
849    }
850
851    #} anything else we may want to filter with.
852    $html = apply_filters( 'zbs_calendar_add_to_calendar', $html );
853
854    return $html;
855}
856
857function zeroBSCRM_task_ui_showOnPortal( $taskObject = array() ) {
858
859    $show = true;
860
861    if ( isset( $taskObject['show_on_portal'] ) ) {
862        $show = $taskObject['show_on_portal'];
863    }
864
865    $html      = "<div class='show-on-calendar'>";
866        $html .= '<div><input name="zbse_show_on_portal" id="zbse_show_on_portal" type="checkbox" value="1"';
867    if ( $show ) {
868        $html .= ' checked="checked"';
869    }
870        $html .= "/><label for='zbse_show_on_portal'>" . __( 'Show on Client Portal (if assigned to contact)', 'zero-bs-crm' ) . '</label></div>';
871    $html     .= '</div>';
872
873    return $html;
874}
875
876function zeroBSCRM_task_ui_comments( $pID = -1 ) {
877
878    $args = array();
879
880    $html = comment_form( $args, $pID );
881
882    return $html;
883}
884
885function zeroBSCRM_task_ui_description( $taskObject = array() ) {
886
887    $html = "<div class='clear'></div><div class='zbs-task-desc'><textarea id='zbse_desc' name='zbse_desc' placeholder='" . __( 'Task Description...', 'zero-bs-crm' ) . "'>";
888
889    if ( isset( $taskObject ) && isset( $taskObject['desc'] ) ) {
890        $html .= $taskObject['desc'];
891    }
892
893    $html .= '</textarea></div>';
894
895    return $html;
896}
897/*
898======================================================
899    / Task UI code
900    ====================================================== */