Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 665
0.00% covered (danger)
0.00%
0 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
zbsDAL_forms
0.00% covered (danger)
0.00%
0 / 664
0.00% covered (danger)
0.00%
0 / 18
45582
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
56
 getSingle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIDList
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getAll
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 getFullCount
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getForm
0.00% covered (danger)
0.00%
0 / 71
0.00% covered (danger)
0.00%
0 / 1
702
 getForms
0.00% covered (danger)
0.00%
0 / 152
0.00% covered (danger)
0.00%
0 / 1
5852
 getFormCount
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
56
 addUpdateForm
0.00% covered (danger)
0.00%
0 / 229
0.00% covered (danger)
0.00%
0 / 1
3422
 addUpdateFormTags
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
90
 deleteForm
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 1
110
 tidy_form
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
42
 getFormMeta
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 getFormOwner
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 db_ready_form
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 listViewObj
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 add_form_view
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 add_form_conversion
0.00% covered (danger)
0.00%
0 / 9
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: 14/01/19
10 */
11
12defined( 'ZEROBSCRM_PATH' ) || exit( 0 );
13
14/**
15 * ZBS DAL >> Forms
16 *
17 * @author   Woody Hayday <hello@jetpackcrm.com>
18 * @version  2.0
19 * @access   public
20 * @see      https://jetpackcrm.com/kb
21 */
22class zbsDAL_forms extends zbsDAL_ObjectLayer {
23
24    protected $objectType     = ZBS_TYPE_FORM;
25    protected $objectDBPrefix = 'zbsf_';
26    protected $objectModel    = array(
27
28        // ID
29        'ID'                  => array(
30            'fieldname' => 'ID',
31            'format'    => 'int',
32        ),
33
34        // site + team generics
35        'zbs_site'            => array(
36            'fieldname' => 'zbs_site',
37            'format'    => 'int',
38        ),
39        'zbs_team'            => array(
40            'fieldname' => 'zbs_team',
41            'format'    => 'int',
42        ),
43        'zbs_owner'           => array(
44            'fieldname' => 'zbs_owner',
45            'format'    => 'int',
46        ),
47
48        // other fields
49        'title'               => array(
50            // db model:
51            'fieldname'   => 'zbsf_title',
52            'format'      => 'str',
53            // output model
54            'input_type'  => 'text',
55            'label'       => 'Form Title',
56            'placeholder' => '',
57            'essential'   => true,
58            'max_len'     => 200,
59        ),
60        'style'               => array(
61            'fieldname' => 'zbsf_style',
62            'format'    => 'str',
63        ),
64        'views'               => array(
65            'fieldname' => 'zbsf_views',
66            'format'    => 'int',
67        ),
68        'conversions'         => array(
69            'fieldname' => 'zbsf_conversions',
70            'format'    => 'int',
71        ),
72        'label_header'        => array(
73            // db model:
74            'fieldname'   => 'zbsf_label_header',
75            'format'      => 'str',
76            // output model
77            'input_type'  => 'text',
78            'label'       => 'Header',
79            'placeholder' => 'Want to find out more?',
80            'nocolumn'    => true,
81            'max_len'     => 200,
82        ),
83        'label_subheader'     => array(
84            // db model:
85            'fieldname'   => 'zbsf_label_subheader',
86            'format'      => 'str',
87            // output model
88            'input_type'  => 'text',
89            'label'       => 'Sub Header',
90            'placeholder' => 'Drop us a line. We follow up on all contacts',
91            'nocolumn'    => true,
92            'max_len'     => 200,
93        ),
94        'label_firstname'     => array(
95            // db model:
96            'fieldname'   => 'zbsf_label_firstname',
97            'format'      => 'str',
98            // output model
99            'input_type'  => 'text',
100            'label'       => 'First Name Placeholder',
101            'placeholder' => 'First Name',
102            'nocolumn'    => true,
103            'max_len'     => 200,
104        ),
105        'label_lastname'      => array(
106            // db model:
107            'fieldname'   => 'zbsf_label_lastname',
108            'format'      => 'str',
109            // output model
110            'input_type'  => 'text',
111            'label'       => 'Last Name Placeholder',
112            'placeholder' => 'Last Name',
113            'nocolumn'    => true,
114            'max_len'     => 200,
115        ),
116        'label_email'         => array(
117            // db model:
118            'fieldname'   => 'zbsf_label_email',
119            'format'      => 'str',
120            // output model
121            'input_type'  => 'text',
122            'label'       => 'Email Placeholder',
123            'placeholder' => 'Email',
124            'nocolumn'    => true,
125            'max_len'     => 200,
126        ),
127        'label_message'       => array(
128            // db model:
129            'fieldname'   => 'zbsf_label_message',
130            'format'      => 'str',
131            // output model
132            'input_type'  => 'text',
133            'label'       => 'Message Placeholder',
134            'placeholder' => 'Your Message',
135            'nocolumn'    => true,
136            'max_len'     => 200,
137        ),
138        'label_button'        => array(
139            // db model:
140            'fieldname'   => 'zbsf_label_button',
141            'format'      => 'str',
142            // output model
143            'input_type'  => 'text',
144            'label'       => 'Submit Button',
145            'placeholder' => 'Submit',
146            'nocolumn'    => true,
147            'max_len'     => 200,
148        ),
149        'label_successmsg'    => array(
150            // db model:
151            'fieldname'   => 'zbsf_label_successmsg',
152            'format'      => 'str',
153            // output model
154            'input_type'  => 'textarea',
155            'label'       => 'Success Message',
156            'placeholder' => 'Thanks. We will be in touch.',
157            'nocolumn'    => true,
158            'max_len'     => 200,
159        ),
160        'label_spammsg'       => array(
161            // db model:
162            'fieldname'   => 'zbsf_label_spammsg',
163            'format'      => 'str',
164            // output model
165            'input_type'  => 'textarea',
166            'label'       => 'Spam Message',
167            'placeholder' => 'We will not send you spam. Our team will be in touch within 24 to 48 hours Mon-Fri (but often much quicker)',
168            'nocolumn'    => true,
169            'max_len'     => 200,
170        ),
171        'include_terms_check' => array(
172            // db model:
173            'fieldname' => 'zbsf_include_terms_check',
174            'format'    => 'bool',
175                /*
176                not live in v3.0, to add v3.1+
177                // output model
178                'input_type' => 'checkbox',
179                'label' => 'Include "Terms and Conditions Check"',
180                'placeholder'=>'',
181                'nocolumn'=>true */
182        ),
183        'terms_url'           => array(
184            // db model:
185            'fieldname' => 'zbsf_terms_url',
186            'format'    => 'str',
187                /*
188                not live in v3.0, to add v3.1+
189                // output model
190                'input_type' => 'text',
191                'label' => 'Terms and Conditions URL',
192                'placeholder'=>'',
193                'nocolumn'=>true,
194                'max_len' => 200 */
195        ),
196        'redir_url'           => array(
197            // db model:
198            'fieldname' => 'zbsf_redir_url',
199            'format'    => 'str',
200                /*
201                not live in v3.0, to add v3.1+
202                // output model
203                'input_type' => 'text',
204                'label' => 'Redirection URL',
205                'placeholder'=>'',
206                'nocolumn'=>true,
207                'max_len' => 200 */
208        ),
209        'font'                => array(
210            'fieldname' => 'zbsf_font',
211            'format'    => 'str',
212        ),
213        'colour_bg'           => array(
214            'fieldname' => 'zbsf_colour_bg',
215            'format'    => 'str',
216        ),
217        'colour_font'         => array(
218            'fieldname' => 'zbsf_colour_font',
219            'format'    => 'str',
220        ),
221        'colour_emphasis'     => array(
222            'fieldname' => 'zbsf_colour_emphasis',
223            'format'    => 'str',
224        ),
225        'created'             => array(
226            'fieldname' => 'zbsf_created',
227            'format'    => 'uts',
228        ),
229        'lastupdated'         => array(
230            'fieldname' => 'zbsf_lastupdated',
231            'format'    => 'uts',
232        ),
233
234    );
235
236    function __construct( $args = array() ) {
237
238        #} =========== LOAD ARGS ==============
239        $defaultArgs = array(
240
241            // 'tag' => false,
242
243        );
244        foreach ( $defaultArgs as $argK => $argV ) {
245            $this->$argK = $argV;
246            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
247                if ( is_array( $args[ $argK ] ) ) {
248                    $newData = $this->$argK;
249                    if ( ! is_array( $newData ) ) {
250                        $newData = array();
251                    } foreach ( $args[ $argK ] as $subK => $subV ) {
252                        $newData[ $subK ] = $subV;
253                    }$this->$argK = $newData;
254                } else {
255                    $this->$argK = $args[ $argK ]; }
256            }
257        }
258        #} =========== / LOAD ARGS =============
259    }
260
261    // ===============================================================================
262    // ===========   FORM  ===========================================================
263
264    // generic get Company (by ID)
265    // Super simplistic wrapper used by edit page etc. (generically called via dal->contacts->getSingle etc.)
266    public function getSingle( $ID = -1 ) {
267
268        return $this->getForm( $ID );
269    }
270
271    // generic get (by ID list)
272    // Super simplistic wrapper used by MVP Export v3.0
273    public function getIDList( $IDs = false ) {
274
275        return $this->getForms(
276            array(
277                'inArr'   => $IDs,
278                'page'    => -1,
279                'perPage' => -1,
280            )
281        );
282    }
283
284    // generic get (EVERYTHING)
285    // expect heavy load!
286    public function getAll( $IDs = false ) {
287
288        return $this->getForms(
289            array(
290                'sortByField' => 'ID',
291                'sortOrder'   => 'ASC',
292                'page'        => -1,
293                'perPage'     => -1,
294            )
295        );
296    }
297
298    // generic get count of (EVERYTHING)
299    public function getFullCount() {
300
301        return $this->getForms(
302            array(
303                'count'   => true,
304                'page'    => -1,
305                'perPage' => -1,
306            )
307        );
308    }
309
310    /**
311     * returns full form line +- details
312     *
313     * @param int id        form id
314     * @param array                 $args   Associative array of arguments
315     *
316     * @return array form object
317     */
318    public function getForm( $id = -1, $args = array() ) {
319
320        global $zbs;
321
322        #} =========== LOAD ARGS ==============
323        $defaultArgs = array(
324
325            // with what?
326            'withTags'    => false,
327            'withOwner'   => false,
328
329            // permissions
330            'ignoreowner' => zeroBSCRM_DAL2_ignoreOwnership( ZBS_TYPE_FORM ), // this'll let you not-check the owner of obj
331
332            // returns scalar ID of line
333            'onlyID'      => false,
334
335            'fields'      => false, // false = *, array = fieldnames
336
337        );
338        foreach ( $defaultArgs as $argK => $argV ) {
339            $$argK = $argV;
340            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
341                if ( is_array( $args[ $argK ] ) ) {
342                    $newData = $$argK;
343                    if ( ! is_array( $newData ) ) {
344                        $newData = array();
345                    } foreach ( $args[ $argK ] as $subK => $subV ) {
346                        $newData[ $subK ] = $subV;
347                    }$$argK = $newData;
348                } else {
349                    $$argK = $args[ $argK ]; }
350            }
351        }
352        #} =========== / LOAD ARGS =============
353
354        #} Check ID
355        $id = (int) $id;
356        if (
357            ( ! empty( $id ) && $id > 0 )
358            ||
359            ( ! empty( $email ) )
360            ||
361            ( ! empty( $externalSource ) && ! empty( $externalSourceUID ) )
362            ) {
363
364            global $ZBSCRM_t, $wpdb;
365            $wheres          = array( 'direct' => array() );
366            $whereStr        = '';
367            $additionalWhere = '';
368            $params          = array();
369            $res             = array();
370            $extraSelect     = '';
371
372            #} ============= PRE-QUERY ============
373
374                $selector = 'form.*';
375            if ( is_array( $fields ) ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
376                    $selector = '';
377
378                    // always needs id, so add if not present
379                if ( ! in_array( 'ID', $fields ) ) {
380                    $selector = 'form.ID';
381                }
382
383                foreach ( $fields as $f ) {
384                    if ( ! empty( $selector ) ) {
385                        $selector .= ',';
386                    }
387                    $selector .= 'form.' . $f;
388                }
389            } elseif ( $onlyID ) {
390                $selector = 'form.ID';
391            }
392
393            #} ============ / PRE-QUERY ===========
394
395            #} Build query
396            $query = 'SELECT ' . $selector . $extraSelect . ' FROM ' . $ZBSCRM_t['forms'] . ' as form';
397            #} ============= WHERE ================
398
399            if ( ! empty( $id ) && $id > 0 ) {
400
401                #} Add ID
402                $wheres['ID'] = array( 'ID', '=', '%d', $id );
403
404            }
405
406            #} ============ / WHERE ==============
407
408            #} Build out any WHERE clauses
409            $wheresArr = $this->buildWheres( $wheres, $whereStr, $params );
410            $whereStr  = $wheresArr['where'];
411            $params    = $params + $wheresArr['params'];
412            #} / Build WHERE
413
414            #} Ownership v1.0 - the following adds SITE + TEAM checks, and (optionally), owner
415            $params = array_merge( $params, $this->ownershipQueryVars( $ignoreowner ) ); // merges in any req.
416            $ownQ   = $this->ownershipSQL( $ignoreowner );
417            if ( ! empty( $ownQ ) ) {
418                $additionalWhere = $this->spaceAnd( $additionalWhere ) . $ownQ; // adds str to query
419            }
420            #} / Ownership
421
422            #} Append to sql (this also automatically deals with sortby and paging)
423            $query .= $this->buildWhereStr( $whereStr, $additionalWhere ) . $this->buildSort( 'ID', 'DESC' ) . $this->buildPaging( 0, 1 );
424
425            try {
426
427                #} Prep & run query
428                $queryObj     = $this->prepare( $query, $params );
429                $potentialRes = $wpdb->get_row( $queryObj, OBJECT );
430
431            } catch ( Exception $e ) {
432
433                #} General SQL Err
434                $this->catchSQLError( $e );
435
436            }
437
438            #} Interpret Results (ROW)
439            if ( isset( $potentialRes ) && isset( $potentialRes->ID ) ) {
440
441                #} Has results, tidy + return
442
443                    #} Only ID? return it directly
444                if ( $onlyID ) {
445                    return $potentialRes->ID;
446                }
447
448                    // tidy
449                if ( is_array( $fields ) ) {
450                    // guesses fields based on table col names
451                    $res = $this->lazyTidyGeneric( $potentialRes );
452                } else {
453                    // proper tidy
454                    $res = $this->tidy_form( $potentialRes );// $withCustomFields
455                }
456
457                if ( $withTags ) {
458
459                    // add all tags lines
460                    $res['tags'] = $this->DAL()->getTagsForObjID(
461                        array(
462                            'objtypeid' => ZBS_TYPE_FORM,
463                            'objid'     => $potentialRes->ID,
464                        )
465                    );
466
467                }
468
469                    return $res;
470
471            }
472        } // / if ID
473
474        return false;
475    }
476
477    /**
478     * returns form detail lines
479     *
480     * @param array $args Associative array of arguments
481     *
482     * @return array of form lines
483     */
484    public function getForms( $args = array() ) {
485
486        global $zbs;
487
488        #} ============ LOAD ARGS =============
489        $defaultArgs = array(
490
491            // Search/Filtering (leave as false to ignore)
492            'searchPhrase' => '', // searches title
493            'inArr'        => false,
494            'isTagged'     => false, // 1x INT OR array(1,2,3)
495            'isNotTagged'  => false, // 1x INT OR array(1,2,3)
496            'ownedBy'      => false,
497            'olderThan'    => false, // uts
498            'newerThan'    => false, // uts
499
500            // returns
501            'count'        => false,
502            'withTags'     => false,
503            'withOwner'    => false,
504            'onlyColumns'  => false, // if passed (array('fname','lname')) will return only those columns (overwrites some other 'return' options). NOTE: only works for base fields (not custom fields)
505
506            'sortByField'  => 'ID',
507            'sortOrder'    => 'ASC',
508            'page'         => 0, // this is what page it is (gets * by for limit)
509            'perPage'      => 100,
510            'whereCase'    => 'AND', // DEFAULT = AND
511
512            // permissions
513            'ignoreowner'  => zeroBSCRM_DAL2_ignoreOwnership( ZBS_TYPE_FORM ), // this'll let you not-check the owner of obj
514
515        );
516        foreach ( $defaultArgs as $argK => $argV ) {
517            $$argK = $argV;
518            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
519                if ( is_array( $args[ $argK ] ) ) {
520                    $newData = $$argK;
521                    if ( ! is_array( $newData ) ) {
522                        $newData = array();
523                    } foreach ( $args[ $argK ] as $subK => $subV ) {
524                        $newData[ $subK ] = $subV;
525                    }$$argK = $newData;
526                } else {
527                    $$argK = $args[ $argK ]; }
528            }
529        }
530        #} =========== / LOAD ARGS =============
531
532        global $ZBSCRM_t, $wpdb, $zbs;
533        $wheres          = array( 'direct' => array() );
534        $whereStr        = '';
535        $additionalWhere = '';
536        $params          = array();
537        $res             = array();
538        $joinQ           = '';
539        $extraSelect     = '';
540
541        #} ============= PRE-QUERY ============
542
543            #} Capitalise this
544            $sortOrder = strtoupper( $sortOrder );
545
546            #} If just count, turn off any extra gumpf
547        if ( $count ) {
548            $withTags  = false;
549            $withOwner = false;
550        }
551
552            #} If onlyColumns, validate
553        if ( $onlyColumns ) {
554
555            #} onlyColumns build out a field arr
556            if ( is_array( $onlyColumns ) && count( $onlyColumns ) > 0 ) {
557
558                $onlyColumnsFieldArr = array();
559                foreach ( $onlyColumns as $col ) {
560
561                    // find db col key from field key (e.g. fname => zbsc_fname)
562                    $dbCol = '';
563                    if ( isset( $this->objectModel[ $col ] ) && isset( $this->objectModel[ $col ]['fieldname'] ) ) {
564                        $dbCol = $this->objectModel[ $col ]['fieldname'];
565                    }
566
567                    if ( ! empty( $dbCol ) ) {
568
569                        $onlyColumnsFieldArr[ $dbCol ] = $col;
570
571                    }
572                }
573            }
574
575            // if legit cols:
576            if ( isset( $onlyColumnsFieldArr ) && is_array( $onlyColumnsFieldArr ) && count( $onlyColumnsFieldArr ) > 0 ) {
577
578                $onlyColumns = true;
579
580                // If onlyColumns, turn off extras
581                $withTags  = false;
582                $withOwner = false;
583
584            } else {
585
586                // deny
587                $onlyColumns = false;
588
589            }
590        }
591
592        #} ============ / PRE-QUERY ===========
593
594        #} Build query
595        $query = 'SELECT form.*' . $extraSelect . ' FROM ' . $ZBSCRM_t['forms'] . ' as form' . $joinQ;
596
597        #} Count override
598        if ( $count ) {
599            $query = 'SELECT COUNT(form.ID) FROM ' . $ZBSCRM_t['forms'] . ' as form' . $joinQ;
600        }
601
602        #} onlyColumns override
603        if ( $onlyColumns && is_array( $onlyColumnsFieldArr ) && count( $onlyColumnsFieldArr ) > 0 ) {
604
605            $columnStr = '';
606            foreach ( $onlyColumnsFieldArr as $colDBKey => $colStr ) {
607
608                if ( ! empty( $columnStr ) ) {
609                    $columnStr .= ',';
610                }
611                // this presumes str is db-safe? could do with sanitation?
612                $columnStr .= $colDBKey;
613
614            }
615
616            $query = 'SELECT ' . $columnStr . ' FROM ' . $ZBSCRM_t['forms'] . ' as form' . $joinQ;
617
618        }
619
620        #} ============= WHERE ================
621
622            #} Add Search phrase
623        if ( ! empty( $searchPhrase ) ) {
624
625            // search? - ALL THESE COLS should probs have index of FULLTEXT in db?
626            $searchWheres                 = array();
627            $searchWheres['search_ID']    = array( 'ID', '=', '%d', $searchPhrase );
628            $searchWheres['search_title'] = array( 'zbsf_title', 'LIKE', '%s', '%' . $searchPhrase . '%' );
629
630            // 3.0.13 - Added ability to search custom fields (optionally)
631            $customFieldSearch = zeroBSCRM_getSetting( 'customfieldsearch' );
632            if ( $customFieldSearch == 1 ) {
633
634                // simplistic add
635                // NOTE: This IGNORES ownership of custom field lines.
636                $searchWheres['search_customfields'] = array( 'ID', 'IN', '(SELECT zbscf_objid FROM ' . $ZBSCRM_t['customfields'] . ' WHERE zbscf_objval LIKE %s AND zbscf_objtype = ' . ZBS_TYPE_FORM . ')', '%' . $searchPhrase . '%' );
637
638            }
639
640            // This generates a query like 'zbsf_fname LIKE %s OR zbsf_lname LIKE %s',
641            // which we then need to include as direct subquery (below) in main query :)
642            $searchQueryArr = $this->buildWheres( $searchWheres, '', array(), 'OR', false );
643
644            if ( is_array( $searchQueryArr ) && isset( $searchQueryArr['where'] ) && ! empty( $searchQueryArr['where'] ) ) {
645
646                // add it
647                $wheres['direct'][] = array( '(' . $searchQueryArr['where'] . ')', $searchQueryArr['params'] );
648
649            }
650        }
651
652            #} In array (if inCompany passed, this'll currently overwrite that?! (todo2.5))
653        if ( is_array( $inArr ) && count( $inArr ) > 0 ) {
654
655            // clean for ints
656            $inArrChecked = array();
657            foreach ( $inArr as $x ) {
658                $inArrChecked[] = (int) $x; }
659
660            // add where
661            $wheres['inarray'] = array( 'ID', 'IN', '(' . implode( ',', $inArrChecked ) . ')' );
662
663        }
664
665            #} Owned by
666        if ( ! empty( $ownedBy ) && $ownedBy > 0 ) {
667
668            // would never hard-type this in (would make generic as in buildWPMetaQueryWhere)
669            // but this is only here until MIGRATED to db2 globally
670            // $wheres['incompany'] = array('ID','IN','(SELECT DISTINCT post_id FROM '.$wpdb->prefix."postmeta WHERE meta_key = 'zbs_company' AND meta_value = %d)",$inCompany);
671            // Use obj links now
672            $wheres['ownedBy'] = array( 'zbs_owner', '=', '%s', $ownedBy );
673
674        }
675
676            // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase,VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
677            // quick addition for mike
678            #} olderThan
679        if ( ! empty( $olderThan ) && $olderThan > 0 ) {
680            $wheres['olderThan'] = array( 'zbsf_created', '<=', '%d', $olderThan );
681        }
682            #} newerThan
683        if ( ! empty( $newerThan ) && $newerThan > 0 ) {
684            $wheres['newerThan'] = array( 'zbsf_created', '>=', '%d', $newerThan );
685        }
686            // phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase,VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
687
688            #} Is Tagged (expects 1 tag ID OR array)
689
690                // catch 1 item arr
691        if ( is_array( $isTagged ) && count( $isTagged ) == 1 ) {
692            $isTagged = $isTagged[0];
693        }
694
695        if ( ! empty( $isTagged ) && ! is_array( $isTagged ) && $isTagged > 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
696
697                // add where tagged
698                // 1 int:
699                $wheres['direct'][] = array( '((SELECT COUNT(ID) FROM ' . $ZBSCRM_t['taglinks'] . ' WHERE zbstl_objtype = %d AND zbstl_objid = form.ID AND zbstl_tagid = %d) > 0)', array( ZBS_TYPE_FORM, $isTagged ) );
700
701        } elseif ( is_array( $isTagged ) && count( $isTagged ) > 0 ) {
702
703            // foreach in array :)
704            $tagStr = '';
705            foreach ( $isTagged as $iTag ) {
706                $i = (int) $iTag;
707                if ( $i > 0 ) {
708
709                    if ( $tagStr !== '' ) {
710                        $tagStr . ',';
711                    }
712                    $tagStr .= $i;
713                }
714            }
715            if ( ! empty( $tagStr ) ) {
716
717                $wheres['direct'][] = array( '((SELECT COUNT(ID) FROM ' . $ZBSCRM_t['taglinks'] . ' WHERE zbstl_objtype = %d AND zbstl_objid = form.ID AND zbstl_tagid IN (%s)) > 0)', array( ZBS_TYPE_FORM, $tagStr ) );
718
719            }
720        }
721            #} Is NOT Tagged (expects 1 tag ID OR array)
722
723                // catch 1 item arr
724        if ( is_array( $isNotTagged ) && count( $isNotTagged ) == 1 ) {
725            $isNotTagged = $isNotTagged[0];
726        }
727
728        if ( ! empty( $isNotTagged ) && ! is_array( $isNotTagged ) && $isNotTagged > 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
729
730                // add where tagged
731                // 1 int:
732                $wheres['direct'][] = array( '((SELECT COUNT(ID) FROM ' . $ZBSCRM_t['taglinks'] . ' WHERE zbstl_objtype = %d AND zbstl_objid = form.ID AND zbstl_tagid = %d) = 0)', array( ZBS_TYPE_FORM, $isNotTagged ) );
733
734        } elseif ( is_array( $isNotTagged ) && count( $isNotTagged ) > 0 ) {
735
736            // foreach in array :)
737            $tagStr = '';
738            foreach ( $isNotTagged as $iTag ) {
739                $i = (int) $iTag;
740                if ( $i > 0 ) {
741
742                    if ( $tagStr !== '' ) {
743                        $tagStr . ',';
744                    }
745                    $tagStr .= $i;
746                }
747            }
748            if ( ! empty( $tagStr ) ) {
749
750                $wheres['direct'][] = array( '((SELECT COUNT(ID) FROM ' . $ZBSCRM_t['taglinks'] . ' WHERE zbstl_objtype = %d AND zbstl_objid = form.ID AND zbstl_tagid IN (%s)) = 0)', array( ZBS_TYPE_FORM, $tagStr ) );
751
752            }
753        }
754
755        #} ============ / WHERE ===============
756
757        #} ============   SORT   ==============
758
759            // Obj Model based sort conversion
760            // converts 'addr1' => 'zbsco_addr1' generically
761        if ( isset( $this->objectModel[ $sortByField ] ) && isset( $this->objectModel[ $sortByField ]['fieldname'] ) ) {
762            $sortByField = $this->objectModel[ $sortByField ]['fieldname'];
763        }
764
765        #} ============ / SORT   ==============
766
767        #} CHECK this + reset to default if faulty
768        if ( ! in_array( $whereCase, array( 'AND', 'OR' ) ) ) {
769            $whereCase = 'AND';
770        }
771
772        #} Build out any WHERE clauses
773        $wheresArr = $this->buildWheres( $wheres, $whereStr, $params, $whereCase );
774        $whereStr  = $wheresArr['where'];
775        $params    = $params + $wheresArr['params'];
776        #} / Build WHERE
777
778        #} Ownership v1.0 - the following adds SITE + TEAM checks, and (optionally), owner
779        $params = array_merge( $params, $this->ownershipQueryVars( $ignoreowner ) ); // merges in any req.
780        $ownQ   = $this->ownershipSQL( $ignoreowner, 'contact' );
781        if ( ! empty( $ownQ ) ) {
782            $additionalWhere = $this->spaceAnd( $additionalWhere ) . $ownQ; // adds str to query
783        }
784        #} / Ownership
785
786        #} Append to sql (this also automatically deals with sortby and paging)
787        $query .= $this->buildWhereStr( $whereStr, $additionalWhere ) . $this->buildSort( $sortByField, $sortOrder ) . $this->buildPaging( $page, $perPage );
788
789        try {
790
791            #} Prep & run query
792            $queryObj = $this->prepare( $query, $params );
793
794            #} Catch count + return if requested
795            if ( $count ) {
796                return $wpdb->get_var( $queryObj );
797            }
798
799            #} else continue..
800            $potentialRes = $wpdb->get_results( $queryObj, OBJECT );
801
802        } catch ( Exception $e ) {
803
804            #} General SQL Err
805            $this->catchSQLError( $e );
806
807        }
808
809        #} Interpret results (Result Set - multi-row)
810        if ( isset( $potentialRes ) && is_array( $potentialRes ) && count( $potentialRes ) > 0 ) {
811
812            #} Has results, tidy + return
813            foreach ( $potentialRes as $resDataLine ) {
814
815                    // using onlyColumns filter?
816                if ( $onlyColumns && is_array( $onlyColumnsFieldArr ) && count( $onlyColumnsFieldArr ) > 0 ) {
817
818                    // only coumns return.
819                    $resArr = array();
820                    foreach ( $onlyColumnsFieldArr as $colDBKey => $colStr ) {
821
822                        if ( isset( $resDataLine->$colDBKey ) ) {
823                            $resArr[ $colStr ] = $resDataLine->$colDBKey;
824                        }
825                    }
826                } else {
827
828                    // tidy
829                    $resArr = $this->tidy_form( $resDataLine );// $withCustomFields
830
831                }
832
833                if ( $withTags ) {
834
835                    // add all tags lines
836                    $resArr['tags'] = $this->DAL()->getTagsForObjID(
837                        array(
838                            'objtypeid' => ZBS_TYPE_FORM,
839                            'objid'     => $resDataLine->ID,
840                        )
841                    );
842
843                }
844
845                    $form_id = $resArr['id'];
846
847                    $res[] = $resArr;
848
849            }
850        }
851
852        return $res;
853    }
854
855    /**
856     * Returns a count of forms (owned)
857     *
858     * @return int count
859     */
860    public function getFormCount( $args = array() ) {
861
862        #} ============ LOAD ARGS =============
863        $defaultArgs = array(
864
865            // Search/Filtering (leave as false to ignore)
866
867            // permissions
868            'ignoreowner' => true, // this'll let you not-check the owner of obj
869
870        );
871        foreach ( $defaultArgs as $argK => $argV ) {
872            $$argK = $argV;
873            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
874                if ( is_array( $args[ $argK ] ) ) {
875                    $newData = $$argK;
876                    if ( ! is_array( $newData ) ) {
877                        $newData = array();
878                    } foreach ( $args[ $argK ] as $subK => $subV ) {
879                        $newData[ $subK ] = $subV;
880                    }$$argK = $newData;
881                } else {
882                    $$argK = $args[ $argK ]; }
883            }
884        }
885        #} =========== / LOAD ARGS =============
886
887        $whereArr = array();
888
889        return $this->DAL()->getFieldByWHERE(
890            array(
891                'objtype'     => ZBS_TYPE_FORM,
892                'colname'     => 'COUNT(ID)',
893                'where'       => $whereArr,
894                'ignoreowner' => $ignoreowner,
895            )
896        );
897    }
898
899    /**
900     * adds or updates a form object
901     *
902     * @param array $args Associative array of arguments
903     *              id (if update), owner, data (array of field data)
904     *
905     * @return int line ID
906     */
907    public function addUpdateForm( $args = array() ) {
908
909        global $ZBSCRM_t, $wpdb, $zbs;
910
911        #} ============ LOAD ARGS =============
912        $defaultArgs = array(
913
914            'id'                   => -1,
915            'owner'                => -1,
916
917            // fields (directly)
918            'data'                 => array(
919
920                'title'               => '',
921                'style'               => '',
922                'views'               => '',
923                'conversions'         => '',
924                'label_header'        => '',
925                'label_subheader'     => '',
926                'label_firstname'     => '',
927                'label_lastname'      => '',
928                'label_email'         => '',
929                'label_message'       => '',
930                'label_button'        => '',
931                'label_successmsg'    => '',
932                'label_spammsg'       => '',
933                'include_terms_check' => '',
934                'terms_url'           => '',
935                'redir_url'           => '',
936                'font'                => '',
937                'colour_bg'           => '',
938                'colour_font'         => '',
939                'colour_emphasis'     => '',
940
941                // tags
942                'tags'                => -1, // pass an array of tag ids or tag strings
943                'tag_mode'            => 'replace', // replace|append|remove
944
945                // allow this to be set for MS sync etc.
946                'created'             => -1,
947                'lastupdated'         => '',
948
949            ),
950
951            'limitedFields'        => -1, // if this is set it OVERRIDES data (allowing you to set specific fields + leave rest in tact)
952            // ^^ will look like: array(array('key'=>x,'val'=>y,'type'=>'%s'))
953
954            // this function as DAL1 func did.
955            'extraMeta'            => -1,
956            'automatorPassthrough' => -1,
957
958            'silentInsert'         => false, // this was for init Migration - it KILLS all IA for newForm (because is migrating, not creating new :) this was -1 before
959
960            'do_not_update_blanks' => false, // this allows you to not update fields if blank (same as fieldoverride for extsource -> in)
961
962        );
963
964        foreach ( $defaultArgs as $argK => $argV ) {
965            $$argK = $argV;
966            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
967                if ( is_array( $args[ $argK ] ) ) {
968                    $newData = $$argK;
969                    if ( ! is_array( $newData ) ) {
970                        $newData = array();
971                    }
972                    foreach ( $args[ $argK ] as $subK => $subV ) {
973                        $newData[ $subK ] = $subV;
974                    }
975                    $$argK = $newData;
976                } else {
977                    $$argK = $args[ $argK ];
978                }
979            }
980        }
981
982        #} =========== / LOAD ARGS ============
983
984        #} ========== CHECK FIELDS ============
985
986            $id = (int) $id;
987
988            // here we check that the potential owner CAN even own
989        if ( $owner > 0 && ! user_can( $owner, 'admin_zerobs_usr' ) ) {
990            $owner = -1;
991        }
992
993            // if owner = -1, add current
994        if ( ! isset( $owner ) || $owner === -1 ) {
995            $owner = zeroBSCRM_user(); }
996
997        if ( is_array( $limitedFields ) ) {
998
999            // LIMITED UPDATE (only a few fields.)
1000            if ( ! is_array( $limitedFields ) || count( $limitedFields ) <= 0 ) {
1001                return false;
1002            }
1003            // REQ. ID too (can only update)
1004            if ( empty( $id ) || $id <= 0 ) {
1005                return false;
1006            }
1007        } else {
1008
1009            // NORMAL, FULL UPDATE
1010
1011        }
1012
1013            #} If no style, add it in
1014        if ( $data['style'] === null || ! isset( $data['style'] ) || empty( $data['style'] ) ) {
1015
1016            // def
1017            $data['style'] = 'simple';
1018
1019        }
1020
1021        #} ========= / CHECK FIELDS ===========
1022
1023        #} ========= OVERRIDE SETTING (Deny blank overrides) ===========
1024
1025            // either ext source + setting, or set by the func call
1026        if ( $do_not_update_blanks ) {
1027
1028                // this setting says 'don't override filled-out data with blanks'
1029                // so here we check through any passed blanks + convert to limitedFields
1030                // only matters if $id is set (there is somt to update not add
1031            if ( isset( $id ) && ! empty( $id ) && $id > 0 ) {
1032
1033                // get data to copy over (for now, this is required to remove 'fullname' etc.)
1034                $dbData = $this->db_ready_form( $data );
1035                // unset($dbData['id']); // this is unset because we use $id, and is update, so not req. legacy issue
1036                // unset($dbData['created']); // this is unset because this uses an obj which has been 'updated' against original details, where created is output in the WRONG format :)
1037
1038                $origData    = $data; // $data = array();
1039                $limitedData = array(); // array(array('key'=>'zbsf_x','val'=>y,'type'=>'%s'))
1040
1041                // cycle through + translate into limitedFields (removing any blanks, or arrays (e.g. externalSources))
1042                // we also have to remake a 'faux' data (removing blanks for tags etc.) for the post-update updates
1043                foreach ( $dbData as $k => $v ) {
1044
1045                    $intV = (int) $v;
1046
1047                    // only add if valuenot empty
1048                    if ( ! is_array( $v ) && ! empty( $v ) && $v != '' && $v !== 0 && $v !== -1 && $intV !== -1 ) {
1049
1050                        // add to update arr
1051                        $limitedData[] = array(
1052                            'key'  => 'zbsf_' . $k, // we have to add zbsf_ here because translating from data -> limited fields
1053                            'val'  => $v,
1054                            'type' => $this->getTypeStr( 'zbsf_' . $k ),
1055                        );
1056
1057                        // add to remade $data for post-update updates
1058                        $data[ $k ] = $v;
1059
1060                    }
1061                }
1062
1063                // copy over
1064                $limitedFields = $limitedData;
1065
1066            } // / if ID
1067
1068        } // / if do_not_update_blanks
1069
1070        #} ========= / OVERRIDE SETTING (Deny blank overrides) ===========
1071
1072        #} ========= BUILD DATA ===========
1073
1074            $update = false;
1075        $dataArr    = array();
1076        $typeArr    = array();
1077
1078        if ( is_array( $limitedFields ) ) {
1079
1080            // LIMITED FIELDS
1081            $update = true;
1082
1083            // cycle through
1084            foreach ( $limitedFields as $field ) {
1085
1086                // some weird case where getting empties, so added check
1087                if ( ! empty( $field['key'] ) ) {
1088                    $dataArr[ $field['key'] ] = $field['val'];
1089                    $typeArr[]                = $field['type'];
1090                }
1091            }
1092
1093            // add update time
1094            if ( ! isset( $dataArr['zbsf_lastupdated'] ) ) {
1095                $dataArr['zbsf_lastupdated'] = time();
1096                $typeArr[]                   = '%d'; }
1097        } else {
1098
1099            // FULL UPDATE/INSERT
1100
1101                // UPDATE
1102                $dataArr = array(
1103
1104                    // ownership
1105                    // no need to update these (as of yet) - can't move teams etc.
1106                    // 'zbs_site' => zeroBSCRM_installSite(),
1107                    // 'zbs_team' => zeroBSCRM_installTeam(),
1108                    // 'zbs_owner' => $owner,
1109
1110                    'zbsf_title'               => $data['title'],
1111                    'zbsf_style'               => $data['style'],
1112                    'zbsf_views'               => $data['views'],
1113                    'zbsf_conversions'         => $data['conversions'],
1114                    'zbsf_label_header'        => $data['label_header'],
1115                    'zbsf_label_subheader'     => $data['label_subheader'],
1116                    'zbsf_label_firstname'     => $data['label_firstname'],
1117                    'zbsf_label_lastname'      => $data['label_lastname'],
1118                    'zbsf_label_email'         => $data['label_email'],
1119                    'zbsf_label_message'       => $data['label_message'],
1120                    'zbsf_label_button'        => $data['label_button'],
1121                    'zbsf_label_successmsg'    => $data['label_successmsg'],
1122                    'zbsf_label_spammsg'       => $data['label_spammsg'],
1123                    'zbsf_include_terms_check' => $data['include_terms_check'],
1124                    'zbsf_terms_url'           => $data['terms_url'],
1125                    'zbsf_redir_url'           => $data['redir_url'],
1126                    'zbsf_font'                => $data['font'],
1127                    'zbsf_colour_bg'           => $data['colour_bg'],
1128                    'zbsf_colour_font'         => $data['colour_font'],
1129                    'zbsf_colour_emphasis'     => $data['colour_emphasis'],
1130                    'zbsf_lastupdated'         => time(),
1131
1132                );
1133
1134                $typeArr = array( // field data types
1135                            // '%d',  // site
1136                            // '%d',  // team
1137                            // '%d',  // owner
1138
1139                    '%s',
1140                    '%s',
1141                    '%d',
1142                    '%d',
1143                    '%s',
1144                    '%s',
1145                    '%s',
1146                    '%s',
1147                    '%s',
1148                    '%s',
1149                    '%s',
1150                    '%s',
1151                    '%s',
1152                    '%d',
1153                    '%s',
1154                    '%s',
1155                    '%s',
1156                    '%s',
1157                    '%s',
1158                    '%s',
1159                    '%d',
1160
1161                );
1162
1163                if ( ! empty( $id ) && $id > 0 ) {
1164
1165                    // is update
1166                    $update = true;
1167
1168                } else {
1169
1170                    // INSERT (get's few extra :D)
1171                    $update               = false;
1172                    $dataArr['zbs_site']  = zeroBSCRM_site();
1173                    $typeArr[]            = '%d';
1174                    $dataArr['zbs_team']  = zeroBSCRM_team();
1175                    $typeArr[]            = '%d';
1176                    $dataArr['zbs_owner'] = $owner;
1177                    $typeArr[]            = '%d';
1178                    if ( isset( $data['created'] ) && ! empty( $data['created'] ) && $data['created'] !== -1 ) {
1179                        $dataArr['zbsf_created'] = $data['created'];
1180                        $typeArr[]               = '%d';
1181                    } else {
1182                        $dataArr['zbsf_created'] = time();
1183                        $typeArr[]               = '%d';
1184                    }
1185                }
1186        }
1187
1188        #} ========= / BUILD DATA ===========
1189
1190        #} ============================================================
1191        #} ========= CHECK force_uniques & not_empty & max_len ========
1192
1193            // if we're passing limitedFields we skip these, for now
1194            // #v3.1 - would make sense to unique/nonempty check just the limited fields. #gh-145
1195        if ( ! is_array( $limitedFields ) ) {
1196
1197            // verify uniques
1198            if ( ! $this->verifyUniqueValues( $data, $id ) ) {
1199                return false; // / fails unique field verify
1200            }
1201
1202            // verify not_empty
1203            if ( ! $this->verifyNonEmptyValues( $data ) ) {
1204                return false; // / fails empty field verify
1205            }
1206        }
1207
1208            // whatever we do we check for max_len breaches and abbreviate to avoid wpdb rejections
1209            $dataArr = $this->wpdbChecks( $dataArr );
1210
1211        #} ========= / CHECK force_uniques & not_empty ================
1212        #} ============================================================
1213
1214        #} Check if ID present
1215        if ( $update ) {
1216
1217                #} Attempt update
1218            if ( $wpdb->update(
1219                $ZBSCRM_t['forms'],
1220                $dataArr,
1221                array( // where
1222                    'ID' => $id,
1223                ),
1224                $typeArr,
1225                array( // where data types
1226                    '%d',
1227                )
1228            ) !== false ) {
1229
1230                        // if passing limitedFields instead of data, we ignore the following
1231                            // this doesn't work, because data is in args default as arr
1232                            // if (isset($data) && is_array($data)){
1233                            // so...
1234                if ( ! isset( $limitedFields ) || ! is_array( $limitedFields ) || $limitedFields == -1 ) {
1235
1236                    // tags
1237                    if ( isset( $data['tags'] ) && is_array( $data['tags'] ) ) {
1238
1239                                $this->addUpdateFormTags(
1240                                    array(
1241                                        'id'        => $id,
1242                                        'tag_input' => $data['tags'],
1243                                        'mode'      => $data['tag_mode'],
1244                                    )
1245                                );
1246
1247                    }
1248                } // / if $data
1249
1250                        #} Any extra meta keyval pairs?
1251                        // BRUTALLY updates (no checking)
1252                        $confirmedExtraMeta = false;
1253                if ( is_array( $extraMeta ) ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable,WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
1254
1255                            $confirmedExtraMeta = array();
1256
1257                    foreach ( $extraMeta as $k => $v ) {
1258
1259                        #} This won't fix stupid keys, just catch basic fails...
1260                        $cleanKey = strtolower( str_replace( ' ', '_', $k ) );
1261
1262                        #} Brutal update
1263                        // update_post_meta($postID, 'zbs_customer_extra_'.$cleanKey, $v);
1264                        $this->DAL()->updateMeta( ZBS_TYPE_FORM, $id, 'extra_' . $cleanKey, $v );
1265
1266                        #} Add it to this, which passes to IA
1267                        $confirmedExtraMeta[ $cleanKey ] = $v;
1268
1269                    }
1270                }
1271
1272                        #} INTERNAL AUTOMATOR
1273                        #} &
1274                        #} FALLBACKS
1275                        // UPDATING CONTACT
1276                if ( ! $silentInsert ) {
1277
1278                    // IA General form update (2.87+)
1279                    zeroBSCRM_FireInternalAutomator(
1280                        'form.update',
1281                        array(
1282                            'id'        => $id,
1283                            'againstid' => $id,
1284                            'data'      => $dataArr,
1285                        )
1286                    );
1287
1288                }
1289
1290                        // Successfully updated - Return id
1291                        return $id;
1292
1293            } else {
1294
1295                $msg = __( 'DB Update Failed', 'zero-bs-crm' );
1296                $zbs->DAL->addError( 302, $this->objectType, $msg, $dataArr );
1297
1298                // FAILED update
1299                return false;
1300
1301            }
1302        } else {
1303
1304            #} No ID - must be an INSERT
1305            if ( $wpdb->insert(
1306                $ZBSCRM_t['forms'],
1307                $dataArr,
1308                $typeArr
1309            ) > 0 ) {
1310
1311                    #} Successfully inserted, lets return new ID
1312                    $newID = $wpdb->insert_id;
1313
1314                    // tags
1315                if ( isset( $data['tags'] ) && is_array( $data['tags'] ) ) {
1316
1317                    $this->addUpdateFormTags(
1318                        array(
1319                            'id'        => $newID,
1320                            'tag_input' => $data['tags'],
1321                            'mode'      => $data['tag_mode'],
1322                        )
1323                    );
1324
1325                }
1326
1327                    #} Any extra meta keyval pairs?
1328                    // BRUTALLY updates (no checking)
1329                    $confirmedExtraMeta = false;
1330                if ( is_array( $extraMeta ) ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable,WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
1331
1332                        $confirmedExtraMeta = array();
1333
1334                    foreach ( $extraMeta as $k => $v ) {
1335
1336                        #} This won't fix stupid keys, just catch basic fails...
1337                        $cleanKey = strtolower( str_replace( ' ', '_', $k ) );
1338
1339                        #} Brutal update
1340                        // update_post_meta($postID, 'zbs_customer_extra_'.$cleanKey, $v);
1341                        $this->DAL()->updateMeta( ZBS_TYPE_FORM, $newID, 'extra_' . $cleanKey, $v );
1342
1343                        #} Add it to this, which passes to IA
1344                        $confirmedExtraMeta[ $cleanKey ] = $v;
1345
1346                    }
1347                }
1348
1349                    #} INTERNAL AUTOMATOR
1350                    #} &
1351                    #} FALLBACKS
1352                    // NEW CONTACT
1353                if ( ! $silentInsert ) {
1354
1355                    #} Add to automator
1356                    zeroBSCRM_FireInternalAutomator(
1357                        'form.new',
1358                        array(
1359                            'id'                   => $newID,
1360                            'data'                 => $dataArr,
1361                            'automatorpassthrough' => $automatorPassthrough, #} This passes through any custom log titles or whatever into the Internal automator recipe.
1362                            'extraMeta'            => $confirmedExtraMeta, #} This is the "extraMeta" passed (as saved)
1363                        )
1364                    );
1365
1366                }
1367
1368                    return $newID;
1369
1370            } else {
1371
1372                $msg = __( 'DB Insert Failed', 'zero-bs-crm' );
1373                $zbs->DAL->addError( 303, $this->objectType, $msg, $dataArr );
1374
1375                #} Failed to Insert
1376                return false;
1377
1378            }
1379        }
1380
1381        return false;
1382    }
1383
1384    /**
1385     * adds or updates a form's tags
1386     * ... this is really just a wrapper for addUpdateObjectTags
1387     *
1388     * @param array $args Associative array of arguments
1389     *              id (if update), owner, data (array of field data)
1390     *
1391     * @return int line ID
1392     */
1393    public function addUpdateFormTags( $args = array() ) {
1394
1395        global $ZBSCRM_t, $wpdb;
1396
1397        #} ============ LOAD ARGS =============
1398        $defaultArgs = array(
1399
1400            'id'        => -1,
1401
1402            // generic pass-through (array of tag strings or tag IDs):
1403            'tag_input' => -1,
1404
1405            // or either specific:
1406            'tagIDs'    => -1,
1407            'tags'      => -1,
1408
1409            'mode'      => 'append',
1410
1411        );
1412        foreach ( $defaultArgs as $argK => $argV ) {
1413            $$argK = $argV;
1414            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
1415                if ( is_array( $args[ $argK ] ) ) {
1416                    $newData = $$argK;
1417                    if ( ! is_array( $newData ) ) {
1418                        $newData = array();
1419                    } foreach ( $args[ $argK ] as $subK => $subV ) {
1420                        $newData[ $subK ] = $subV;
1421                    }$$argK = $newData;
1422                } else {
1423                    $$argK = $args[ $argK ]; }
1424            }
1425        }
1426        #} =========== / LOAD ARGS ============
1427
1428        #} ========== CHECK FIELDS ============
1429
1430            // check id
1431            $id = (int) $id;
1432        if ( empty( $id ) || $id <= 0 ) {
1433            return false;
1434        }
1435
1436        #} ========= / CHECK FIELDS ===========
1437
1438        return $this->DAL()->addUpdateObjectTags(
1439            array(
1440                'objtype'   => ZBS_TYPE_FORM,
1441                'objid'     => $id,
1442                'tag_input' => $tag_input,
1443                'tags'      => $tags,
1444                'tagIDs'    => $tagIDs,
1445                'mode'      => $mode,
1446            )
1447        );
1448    }
1449
1450    /**
1451     * deletes a form object
1452     *
1453     * @param array $args Associative array of arguments
1454     *              id
1455     *
1456     * @return int success;
1457     */
1458    public function deleteForm( $args = array() ) {
1459
1460        global $ZBSCRM_t, $wpdb, $zbs;
1461
1462        #} ============ LOAD ARGS =============
1463        $defaultArgs = array(
1464
1465            'id'          => -1,
1466            'saveOrphans' => true,
1467
1468        );
1469        foreach ( $defaultArgs as $argK => $argV ) {
1470            $$argK = $argV;
1471            if ( is_array( $args ) && isset( $args[ $argK ] ) ) {
1472                if ( is_array( $args[ $argK ] ) ) {
1473                    $newData = $$argK;
1474                    if ( ! is_array( $newData ) ) {
1475                        $newData = array();
1476                    } foreach ( $args[ $argK ] as $subK => $subV ) {
1477                        $newData[ $subK ] = $subV;
1478                    }$$argK = $newData;
1479                } else {
1480                    $$argK = $args[ $argK ]; }
1481            }
1482        }
1483        #} =========== / LOAD ARGS ============
1484
1485        #} Check ID & Delete :)
1486        $id = (int) $id;
1487        if ( ! empty( $id ) && $id > 0 ) {
1488
1489            // delete orphans?
1490            if ( $saveOrphans === false ) {
1491
1492                // delete any tag links
1493                $this->DAL()->deleteTagObjLinks(
1494                    array(
1495
1496                        'objtype' => ZBS_TYPE_FORM,
1497                        'objid'   => $id,
1498                    )
1499                );
1500
1501                // delete any external source information
1502                $this->DAL()->delete_external_sources(
1503                    array(
1504
1505                        'obj_type'   => ZBS_TYPE_FORM,
1506                        'obj_id'     => $id,
1507                        'obj_source' => 'all',
1508
1509                    )
1510                );
1511            }
1512
1513            $del = zeroBSCRM_db2_deleteGeneric( $id, 'forms' );
1514
1515            #} Add to automator
1516            zeroBSCRM_FireInternalAutomator(
1517                'form.delete',
1518                array(
1519                    'id'          => $id,
1520                    'saveOrphans' => $saveOrphans,
1521                )
1522            );
1523
1524            return $del;
1525
1526        }
1527
1528        return false;
1529    }
1530
1531    /**
1532     * tidy's the object from wp db into clean array
1533     *
1534     * @param array $obj (DB obj)
1535     *
1536     * @return array form (clean obj)
1537     */
1538    private function tidy_form( $obj = false, $withCustomFields = false ) {
1539
1540            $res = false;
1541
1542        if ( isset( $obj->ID ) ) {
1543            $res       = array();
1544            $res['id'] = $obj->ID;
1545            /*
1546            `zbs_site` INT NULL DEFAULT NULL,
1547            `zbs_team` INT NULL DEFAULT NULL,
1548            `zbs_owner` INT NOT NULL,
1549            */
1550            $res['owner'] = $obj->zbs_owner;
1551
1552            $res['title']               = $this->stripSlashes( $obj->zbsf_title );
1553            $res['style']               = $this->stripSlashes( $obj->zbsf_style );
1554            $res['views']               = (int) $obj->zbsf_views;
1555            $res['conversions']         = (int) $obj->zbsf_conversions;
1556            $res['label_header']        = $this->stripSlashes( $obj->zbsf_label_header );
1557            $res['label_subheader']     = $this->stripSlashes( $obj->zbsf_label_subheader );
1558            $res['label_firstname']     = $this->stripSlashes( $obj->zbsf_label_firstname );
1559            $res['label_lastname']      = $this->stripSlashes( $obj->zbsf_label_lastname );
1560            $res['label_email']         = $this->stripSlashes( $obj->zbsf_label_email );
1561            $res['label_message']       = $this->stripSlashes( $obj->zbsf_label_message );
1562            $res['label_button']        = $this->stripSlashes( $obj->zbsf_label_button );
1563            $res['label_successmsg']    = $this->stripSlashes( $obj->zbsf_label_successmsg );
1564            $res['label_spammsg']       = $this->stripSlashes( $obj->zbsf_label_spammsg );
1565            $res['include_terms_check'] = (bool) $obj->zbsf_include_terms_check;
1566            $res['terms_url']           = $this->stripSlashes( $obj->zbsf_terms_url );
1567            $res['redir_url']           = $this->stripSlashes( $obj->zbsf_redir_url );
1568            $res['font']                = $this->stripSlashes( $obj->zbsf_font );
1569            $res['colour_bg']           = $this->stripSlashes( $obj->zbsf_colour_bg );
1570            $res['colour_font']         = $this->stripSlashes( $obj->zbsf_colour_font );
1571            $res['colour_emphasis']     = $this->stripSlashes( $obj->zbsf_colour_emphasis );
1572            $res['created']             = (int) $obj->zbsf_created;
1573            // $res['created_date'] = (isset($obj->zbsf_created) && $obj->zbsf_created > 0) ? zeroBSCRM_locale_utsToDatetime($obj->zbsf_created) : false;
1574            $res['created_date'] = ( isset( $obj->zbsf_created ) && $obj->zbsf_created > 0 ) ? zeroBSCRM_date_i18n( -1, $obj->zbsf_created, false, true ) : false;
1575            $res['lastupdated']  = (int) $obj->zbsf_lastupdated;
1576            // $res['lastupdated_date'] = (isset($obj->zbsf_lastupdated) && $obj->zbsf_lastupdated > 0) ? zeroBSCRM_locale_utsToDatetime($obj->zbsf_lastupdated) : false;
1577            $res['lastupdated_date'] = ( isset( $obj->zbsf_lastupdated ) && $obj->zbsf_lastupdated > 0 ) ? zeroBSCRM_date_i18n( -1, $obj->zbsf_lastupdated, false, true ) : false;
1578
1579        }
1580
1581        return $res;
1582    }
1583
1584    /**
1585     * Wrapper, use $this->getFormMeta($contactID,$key) for easy retrieval of singular form
1586     * Simplifies $this->getMeta
1587     *
1588     * @param int objtype
1589     * @param int objid
1590     * @param string key
1591     *
1592     * @return array form meta result
1593     */
1594    public function getFormMeta( $id = -1, $key = '', $default = false ) {
1595
1596        global $zbs;
1597
1598        if ( ! empty( $key ) ) {
1599
1600            return $this->DAL()->getMeta(
1601                array(
1602
1603                    'objtype'     => ZBS_TYPE_FORM,
1604                    'objid'       => $id,
1605                    'key'         => $key,
1606                    'fullDetails' => false,
1607                    'default'     => $default,
1608                    'ignoreowner' => true, // for now !!
1609
1610                )
1611            );
1612
1613        }
1614
1615        return $default;
1616    }
1617
1618    /**
1619     * Returns an ownerid against a form
1620     *
1621     * @param int id form ID
1622     *
1623     * @return int form owner id
1624     */
1625    public function getFormOwner( $id = -1 ) {
1626
1627        global $zbs;
1628
1629        $id = (int) $id;
1630
1631        if ( $id > 0 ) {
1632
1633            return $this->DAL()->getFieldByID(
1634                array(
1635                    'id'          => $id,
1636                    'objtype'     => ZBS_TYPE_FORM,
1637                    'colname'     => 'zbs_owner',
1638                    'ignoreowner' => true,
1639                )
1640            );
1641
1642        }
1643
1644        return false;
1645    }
1646
1647    /**
1648     * remove any non-db fields from the object
1649     * basically takes array like array('owner'=>1,'fname'=>'x','fullname'=>'x')
1650     * and returns array like array('owner'=>1,'fname'=>'x')
1651     * This does so based on the objectModel!
1652     *
1653     * @param array $obj (clean obj)
1654     *
1655     * @return array (db ready arr)
1656     */
1657    private function db_ready_form( $obj = false ) {
1658
1659        // use the generic? (override here if necessary)
1660        return $this->db_ready_obj( $obj );
1661    }
1662
1663    /**
1664     * Takes full object and makes a "list view" boiled down version
1665     * Used to generate listview objs
1666     *
1667     * @param array $obj (clean obj)
1668     *
1669     * @return array (listview ready obj)
1670     */
1671    public function listViewObj( $form = false, $columnsRequired = array() ) {
1672
1673        if ( is_array( $form ) && isset( $form['id'] ) ) {
1674
1675            $resArr = $form;
1676
1677            // a lot of this is legacy <DAL3 stuff just mapped. def could do with an improvement for efficacy's sake.
1678            // lol needed none for DAL 3 :) perfect object.
1679
1680            // $resArr['style']        = get_post_meta($form['id'], 'zbs_form_style',true);
1681            // $resArr['views']        = get_post_meta($form['id'], 'zbs_form_views',true);
1682            // $resArr['conversions']  = get_post_meta($form['id'], 'zbs_form_conversions',true);
1683            // $resArr['id'] = $form['id'];
1684            // $resArr['title'] = $form['title'];
1685
1686            // $d = new DateTime($form['created']);
1687            // $formatted_date = $d->format(zeroBSCRM_getDateFormat());
1688
1689            // use Proper field $resArr['added'] = $formatted_date;
1690
1691            return $resArr;
1692
1693        }
1694
1695        return false;
1696    }
1697
1698    /**
1699     * Increase the form views in +1
1700     *
1701     * @param $form_id The form ID
1702     * @return mixed Return the total views
1703     */
1704    public function add_form_view( $form_id ) {
1705        $form = $this->getForm( $form_id );
1706        ++$form['views'];
1707
1708        $this->addUpdateForm(
1709            array(
1710                'id'   => $form_id,
1711                'data' => $form,
1712            )
1713        );
1714
1715        return $form['views'];
1716    }
1717
1718    /**
1719     * Increase the form conversions in +1
1720     *
1721     * @param $form_id The form ID
1722     * @return mixed Return the total conversions
1723     */
1724    public function add_form_conversion( $form_id ) {
1725        $form = $this->getForm( $form_id );
1726        ++$form['conversions'];
1727
1728        $this->addUpdateForm(
1729            array(
1730                'id'   => $form_id,
1731                'data' => $form,
1732            )
1733        );
1734
1735        return $form['conversions'];
1736    }
1737
1738    // ===========  /   FORM  =======================================================
1739    // ===============================================================================
1740} // / class