Passed
Branchfeature/useWidgetsNamespaces (eb4650)
by Robin
02:57
created

Func_App::AppCustomFieldSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
//-------------------------------------------------------------------------
4
// OVIDENTIA http://www.ovidentia.org
5
// Ovidentia is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2, or (at your option)
8
// any later version.
9
//
10
// This program is distributed in the hope that it will be useful, but
11
// WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
// See the GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18
// USA.
19
//-------------------------------------------------------------------------
20
/**
21
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
22
 * @copyright Copyright (c) 2018 by CANTICO ({@link http://www.cantico.fr})
23
 */
24
namespace Capwelton\LibApp;
25
26
use Capwelton\LibApp\Exceptions\AppException;
27
use Capwelton\LibApp\Ctrl\AppController;
28
use Capwelton\LibApp\Set\AppCustomContainerSet;
29
use Capwelton\LibApp\Set\AppCustomFieldSet;
30
use Capwelton\LibApp\Set\AppCustomSectionSet;
31
use Capwelton\LibApp\Ui\AppUi;
32
use Capwelton\LibApp\Set\AppRecord;
33
use Capwelton\LibApp\Set\AppSSESet;
34
use Capwelton\LibApp\Set\AppNotificationSet;
35
use Capwelton\LibApp\Set\AppLinkSet;
36
use Capwelton\LibApp\Set\AppLogSet;
37
use Capwelton\LibOrm\Func_LibOrm;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Func_LibOrm was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
38
use Capwelton\LibOrm\ORMRecordSet;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\ORMRecordSet was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
39
use Capwelton\LibOrm\MySql\ORMMySqlBackend;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\MySql\ORMMySqlBackend was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
41
require_once dirname(__FILE__) . '/define.php';
42
require_once dirname(__FILE__) . '/functions.php';
43
44
$libappAddon = bab_getAddonInfosInstance('libapp');
45
$libappPhpPath = $libappAddon->getPhpPath();
46
47
require_once $libappPhpPath . '../vendor/autoload.php';
48
49
/**
50
 * Provides extensible functionalities to manage an application.
51
 *
52
 * @method AppCustomFieldSet       CustomFieldSet()
53
 * @method AppCustomSectionSet     CustomSectionSet()
54
 * @method AppCustomContainerSet   CustomContainerSet()
55
 */
56
class Func_App extends \bab_Functionality
57
{
58
    public $addonPrefix;
59
    public $classPrefix;
60
    public $addonName;
61
    public $controllerTg;
62
    public $phpPath;
63
    public $recordSetPath;
64
    public $ctrlPath;
65
    public $uiPath;
66
    
67
    private $components = array();
68
    private $currentComponent;
69
70
71
    /**
72
     * @var string
73
     */
74
    private $language = null;
75
76
77
    public function __construct()
78
    {
79
        $this->addonName = 'libapp';
80
        $this->addonPrefix = 'app';
81
82
        $this->classPrefix = 'App';
83
        $this->controllerTg = 'addon/' . $this->addonName . '/main';
84
85
        $addon = bab_getAddonInfosInstance($this->addonName);
86
        $this->phpPath = $addon->getPhpPath();
87
        $this->recordSetPath = $this->phpPath;
88
        $this->ctrlPath = $this->phpPath;
89
        $this->uiPath = $this->phpPath . 'ui/';
90
91
        $babDB = bab_getDB();
92
93
        /** @var $LibOrm Func_LibOrm */
94
        $LibOrm = \bab_Functionality::get('LibOrm');
95
96
        $LibOrm->initMysql();
97
        ORMRecordSet::setBackend(new ORMMySqlBackend($babDB));
98
    }
99
    
100
    public function addComponentsFromName($componentName)
101
    {
102
        $componentDefinitionObjectName = 'Capwelton\App\\'.$componentName.'\ComponentDefinition\ComponentDefinition';
103
        if (class_exists($componentDefinitionObjectName)) {
104
            $componentDefinition = new $componentDefinitionObjectName;
105
            $components = $componentDefinition->getComponents($this);
106
            foreach ($components as $singleName => $singleComponent){
107
                $this->addComponent($singleName, $singleComponent);
108
            }
109
        }
110
        
111
        return $this;
112
    }
113
    
114
    public function createComponent($set, $ctrl, $ui)
115
    {
116
        return new AppComponent($this, $set, $ctrl, $ui);
117
    }
118
    
119
    public function addComponent($componentName, AppComponent $component)
120
    {
121
        $this->components[$componentName] = $component;
122
        return $this;
123
    }
124
    
125
    /**
126
     * @param string $componentName
127
     * @return AppComponent|NULL
128
     */
129
    public function getComponentByName($componentName)
130
    {
131
        $componentName = explode('_', $componentName);
132
        $nbElem = count($componentName);
133
        $componentName = $componentName[$nbElem - 1];
134
        $componentName = strtoupper($componentName);
135
        if(isset($this->components[$componentName])){
136
            return $this->components[$componentName];
137
        }
138
        return null;
139
    }
140
    
141
    public function setCurrentComponent(AppComponent $component = null)
142
    {
143
        $this->currentComponent = $component;
144
        return $this;
145
    }
146
    
147
    public function setCurrentComponentByName($componentName = null)
148
    {
149
        $component = $this->getComponentByName($componentName);
150
        $this->currentComponent = $component;
151
        return $this;
152
    }
153
    
154
    /**
155
     * @return AppComponent|null
156
     */
157
    public function getCurrentComponent()
158
    {
159
        return $this->currentComponent;
160
    }
161
    
162
    public function __get($componentName)
163
    {
164
        if(isset($this->components[$componentName])){
165
            return $this->components[$componentName];
166
        }else{
167
            return null;
168
        }
169
    }
170
171
    /**
172
     * @return AppComponent[]
173
     */
174
    public function getComponents()
175
    {
176
        return $this->components;
177
    }
178
    
179
    public function checkComponentsDependencies()
180
    {
181
        $components = $this->getComponents();
182
        
183
        $messages = array();
184
        
185
        foreach ($components as $componentName => $component){
186
            $dependencies = $component->checkDependencies();
187
            foreach($dependencies['requiredComponents'] as $requiredComponent){
188
                $messages['requiredComponents'][$componentName][] = $requiredComponent;
189
            }
190
            foreach($dependencies['optionalComponents'] as $optionalComponent){
191
                $messages['optionalComponents'][$componentName][] = $optionalComponent;
192
            }
193
        }
194
        
195
        return $messages;
196
    }
197
198
    public function getComponentDefinitions()
199
    {
200
        $components = $this->getComponents();
201
        $componentDefinitions = array();
202
        foreach ($components as $component){
203
            $packageName = $component->getPackageName();
204
            if(isset($componentDefinitions[$packageName]) && !empty($componentDefinitions[$packageName])){
205
                continue;
206
            }
207
            $componentDefinitions[$packageName] = $component->getDefinition();
208
        }
209
        return $componentDefinitions;
210
    }
211
212
    /**
213
     * @param string $class
214
     * @return boolean
215
     */
216
    public function loadObject($class)
217
    {
218
        $classPrefix = $this->classPrefix;
219
220
        if (substr($class, 0, strlen($classPrefix)) === $classPrefix) {
221
            if (substr($class, -3) === 'Set') {
222
                $pathname = $this->getRecordSetPathname($class);
223
                if (file_exists($pathname)) {
224
                    require $pathname;
225
                    return true;
226
                }
227
            } else {
228
                $pathname = $this->getRecordPathname($class);
229
                if (file_exists($pathname)) {
230
                    require $pathname;
231
                    return true;
232
                }
233
            }
234
        }
235
        return false;
236
    }
237
238
    /**
239
     * Returns the expected pathname for the file containing the definition of the record set class.
240
     *
241
     * @param string $class
242
     * @return string
243
     */
244
    public function getRecordSetPathname($class)
245
    {
246
        // $App->MyRecordSet() -> myrecord.class.php
247
        $file = strtolower(substr($class, strlen($this->classPrefix), -3)) . '.class.php';
248
        return $this->recordSetPath . $file;
249
    }
250
251
    /**
252
     *  Returns the expected pathname for the file containing the definition of the record class.
253
     *
254
     * @param string $class
255
     * @return string
256
     */
257
    public function getRecordPathname($class)
258
    {
259
        // $App->MyRecord() -> myrecord.class.php
260
        $file = strtolower(substr($class, strlen($this->classPrefix))) . '.class.php';
261
        return $this->recordSetPath . $file;
262
    }
263
264
    /**
265
     * @return string
266
     */
267
    public function getUiPath()
268
    {
269
        return APP_UI_PATH;
270
    }
271
272
    /**
273
     * @return string
274
     */
275
    public function getSetPath()
276
    {
277
        return APP_SET_PATH;
278
    }
279
280
    /**
281
     * @return string
282
     */
283
    public function getCtrlPath()
284
    {
285
        return APP_CTRL_PATH;
286
    }
287
288
    /**
289
     * @return string
290
     */
291
    public function getPhpPath()
292
    {
293
        return APP_PHP_PATH;
294
    }
295
296
297
    /**
298
     * @return string
299
     *
300
     */
301
    public function getDescription()
302
    {
303
        return 'Application framework.';
304
    }
305
306
307
    /**
308
     * Get the addon name
309
     * @return string
310
     */
311
    public function getAddonName()
312
    {
313
        return $this->addonName;
314
    }
315
316
317
    /**
318
     * @return \bab_addonInfos
319
     */
320
    public function getAddon()
321
    {
322
        return bab_getAddonInfosInstance($this->getAddonName());
323
    }
324
325
326
    /**
327
     * Register myself as a functionality.
328
     *
329
     */
330
    public static function register()
331
    {
332
        $addon = bab_getAddonInfosInstance('libapp');
333
334
        $addon->registerFunctionality('App', 'app.php');
335
    }
336
337
338
    /**
339
     * Synchronize sql tables for all classes found in Application object
340
     * using methods  'includeXxxxxClassName'
341
     * sychronize if the two correspond methods are met and the set classname match the prefix from parameter
342
     * do not synchronize if the set method has a VueSet suffix, in this case the table si juste a readonly vue
343
     *
344
     * @param	string	$prefix		tables and classes prefix
345
     * @return \bab_synchronizeSql
346
     */
347
    public function synchronizeSql($prefix)
348
    {
349
        if (!$prefix) {
350
            return null;
351
        }
352
353
        require_once $GLOBALS['babInstallPath'].'utilit/devtools.php';
354
        $mysqlbackend = new ORMMySqlBackend($GLOBALS['babDB']);
355
        $sql = 'SET FOREIGN_KEY_CHECKS=0;
356
            ';
357
358
        foreach (get_class_methods($this) as $method) {
359
360
            if (substr($method, 0, 7) === 'include' && substr($method, -3) === 'Set') {
361
                $incl = $method;
362
                $classNameMethod = substr($method, strlen('include')) . 'ClassName';
363
364
365
                $classname = $this->$classNameMethod();
366
367
                if ($prefix === substr($classname, 0, strlen($prefix))
368
                  && 'Set' === substr($classname, -3)
369
                  && 'ViewSet' !== substr($classname, -7)) {
370
                    if (method_exists($this, $incl)) {
371
                        $this->$incl();
372
373
                        $call = substr($classname, strlen($prefix));
374
375
                        if (class_exists($classname)) {
376
377
                            /* @var $set ORMRecordSet */
378
                            $set = $this->$call();
379
                            if (method_exists($set, 'useLang')) {
380
                                // This is necessary if the recordSet constructor uses a setLang().
381
                                // We need to revert to multilang fields before synchronizing.
382
                                $set->useLang(false);
383
                            }
384
                            $sql .= $mysqlbackend->setToSql($set) . "\n";
385
                        }
386
                    }
387
                }
388
            }
389
        }
390
391
        require_once $GLOBALS['babInstallPath'].'utilit/devtools.php';
392
        $synchronize = new \bab_synchronizeSql();
393
394
        $synchronize->fromSqlString($sql);
395
396
        return $synchronize;
397
    }
398
    
399
    public function synchronizeComponentsSql($prefix)
400
    {
401
        if (!$prefix) {
402
            return null;
403
        }
404
        
405
        require_once $GLOBALS['babInstallPath'].'utilit/devtools.php';
406
        $mysqlbackend = new ORMMySqlBackend($GLOBALS['babDB']);
407
        $sql = 'SET FOREIGN_KEY_CHECKS=0;
408
            ';
409
410
        $noPackageNames = array();
411
        foreach ($this->components as $component){
412
            /* @var $component AppComponent */
413
            try{
414
                /* @var $set ORMRecordSet */
415
                $set = $component->recordSet();
416
                //Check if the component is not overriden by the addon
417
                //This is to prevent the destruction of non-generic fields on addon update, that will next be re-created by the overriden set
418
                //In case the set has been overriden, we simply do nothing here, as it will be instanciated by the synchronizeSql method
419
                $cmprc = new \ReflectionClass($set);
420
                $componentSetClass = $cmprc->getShortName();
421
                if(method_exists($this, $componentSetClass)){
422
                    continue;
423
                }
424
                if(method_exists($set, 'useLang')){
425
                    // This is necessary if the recordSet constructor uses a setLang().
426
                    // We need to revert to multilang fields before synchronizing.
427
                    $set->useLang(false);
428
                }
429
                $sql .= $mysqlbackend->setToSql($set) . "\n";
430
                
431
                if(empty($component->getPackageName())){
432
                    $noPackageNames[] = $component->getName();
433
                }
434
            }
435
            catch (\Exception $e){
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
436
                
437
            }
438
        }
439
        
440
        if(!empty($noPackageNames)){
441
            $errorMessage = implode(', ', $noPackageNames);
442
            \bab_installWindow::message(
443
                sprintf(
444
                    $this->translate(
445
                        'The following component does not have a package name : %s. The method setPackageName must be called on the component creation',
446
                        'The following components do not have a package name : %s. The method setPackageName must be called on the components creation',
447
                        count($noPackageNames)
448
                    ),
449
                    $errorMessage
450
                )
451
            );
452
            \bab_installWindow::message(
453
                $this->translate('Terminating script with errors')
454
            );
455
            throw new AppException($this->translate('Components package name error'));
456
        }
457
        
458
        require_once $GLOBALS['babInstallPath'].'utilit/devtools.php';
459
        $synchronize = new \bab_synchronizeSql();
460
        
461
        $synchronize->fromSqlString($sql);
462
        
463
        $dependencies = $this->checkComponentsDependencies();
464
        foreach ($dependencies['requiredComponents'] as $componentName => $requiredComponents){
465
            foreach ($requiredComponents as $requiredComponent){
466
                $hasComponent = $this->getComponentByName($requiredComponent);
467
                if(!$hasComponent){
468
                    \bab_installWindow::message(sprintf($this->translate('The component %s is required for the component %s to work. You will encounter fatal errors'), $requiredComponent, $componentName));
469
                }
470
            }
471
        }
472
        foreach ($dependencies['optionalComponents'] as $componentName => $optionalComponents){
473
            foreach ($optionalComponents as $optionalComponent){
474
                $hasComponent = $this->getComponentByName($optionalComponent);
475
                if(!$hasComponent){
476
                    \bab_installWindow::message(sprintf($this->translate('The optional component %s has not been added. The component %s may have reduced functionalities'), $optionalComponent, $componentName));
477
                }
478
            }
479
        }
480
        
481
        return $synchronize;
482
    }
483
484
    public function componentsOnUpdate()
485
    {
486
        $components = $this->getComponents();
487
        
488
        foreach ($components as $component){
489
            $component->onUpdate();
490
        }
491
        
492
        return $this;
493
    }
494
495
    public function getSynchronizeSql($prefix)
496
    {
497
        if (!$prefix) {
498
            return null;
499
        }
500
501
        require_once $GLOBALS['babInstallPath'].'utilit/devtools.php';
502
        $mysqlbackend = new ORMMySqlBackend($GLOBALS['babDB']);
503
        $sql = '';
504
505
        foreach (get_class_methods($this) as $method) {
506
507
            if (substr($method, 0, strlen('include')) === 'include' && substr($method, -strlen('Set')) === 'Set') {
508
                $incl = $method;
509
                $classNameMethod = substr($method, strlen('include')) . 'ClassName';
510
511
                $classname = $this->$classNameMethod();
512
513
                if ($prefix === substr($classname, 0, strlen($prefix))
514
                    && 'Set' === substr($classname, -3)
515
                    && 'ViewSet' !== substr($classname, -6)
516
                    ) {
517
                        if (method_exists($this, $incl)) {
518
                            $this->$incl();
519
                            $call = substr($classname, strlen($prefix));
520
521
                            if (class_exists($classname) && method_exists($this, $call)) {
522
                                $set = $this->$call();
523
                                $sql .= $mysqlbackend->setToSql($set) . "\n";
524
                            }
525
                        }
526
                    }
527
            }
528
        }
529
530
        return $sql;
531
    }
532
533
534
535
    public function includeBase()
536
    {
537
        require_once APP_PHP_PATH . 'base.class.php';
538
    }
539
540
    /**
541
     * Includes app_RecordSet class definition.
542
     */
543
    public function includeRecordSet()
544
    {
545
//         require_once APP_SET_PATH . 'record.class.php';
546
    }
547
548
549
    /**
550
     * Includes app_TraceableRecordSet class definition.
551
     */
552
    public function includeTraceableRecordSet()
553
    {
554
//         require_once APP_SET_PATH . 'traceablerecord.class.php';
555
    }
556
557
558
    /**
559
     *
560
     * @return AppAccessManager
561
     */
562
    public function AccessManager()
563
    {
564
        static $accessManager = null;
565
        if (!isset($accessManager)) {
566
            $accessManager = new AppAccessManager($this);
567
        }
568
569
        return $accessManager;
570
    }
571
572
    
573
574
    /**
575
     *
576
     * @param string $recordClassname
577
     *
578
     * @return ORMRecordSet
579
     */
580
    public function getRecordSetByRef($recordClassname)
581
    {
582
        $recordClassname = str_replace($this->classPrefix, '', $recordClassname);
583
        $classSet = $recordClassname . 'Set';
584
        $set = $this->$classSet();
585
        return $set;
586
    }
587
588
    /**
589
     * Returns the app_Record corresponding to the specified
590
     * reference $ref.
591
     *
592
     * @param string 	$ref	A reference string (e.g. Contact:12)
593
     * @return AppRecord	or null if no corresponding record is found.
594
     */
595
    public function getRecordByRef($ref, $noDefaultCriteria = false)
596
    {
597
        $refParts = explode(':', $ref);
598
        if (count($refParts) !== 2) {
599
            return null;
600
        }
601
        list($recordClassname, $id) = $refParts;
602
        $set = $this->getRecordSetByRef($recordClassname);
603
        if (isset($set)) {
604
            if($noDefaultCriteria){
605
                $set->setDefaultCriteria(null);
606
            }
607
            return $set->get($id);
608
        }
609
        return null;
610
    }
611
612
    /**
613
     * Returns the reference corresponding to the specified
614
     * app_Record $record (e.g. Contact:12 or Deal:125)
615
     *
616
     * @param AppRecord	$record
617
     * @return string
618
     */
619
    public function getRecordRef(AppRecord $record)
620
    {
621
        $fullClassName = get_class($record);
622
        list(, $className) = explode('_', $fullClassName);
623
        return $className . ':' . $record->id;
624
    }
625
626
627
    /**
628
     *
629
     * @return \Func_Translate_Gettext
0 ignored issues
show
Bug introduced by
The type Func_Translate_Gettext was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
630
     */
631
    private static function getTranslator()
632
    {
633
        /**  @var $translator \Func_Translate_Gettext */
634
        static $translator = null;
635
        if (!isset($translator)) {
636
637
            $translator = \bab_functionality::get('Translate/Gettext', false);
638
            $translator->setAddonName('libapp');
0 ignored issues
show
Bug introduced by
The method setAddonName() does not exist on bab_functionality. It seems like you code against a sub-type of bab_functionality such as Capwelton\LibApp\Func_App. ( Ignorable by Annotation )

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

638
            $translator->/** @scrutinizer ignore-call */ 
639
                         setAddonName('libapp');
Loading history...
639
        }
640
641
        return $translator;
642
    }
643
644
645
    /**
646
     * Specifies the language to use for translation.
647
     *
648
     * If $language is null, the language is reset to
649
     * the current logged user language.
650
     *
651
     * @param string|null $language
652
     */
653
    public function setTranslateLanguage($language)
654
    {
655
        $this->language = $language;
656
    }
657
658
659
660
    /**
661
     * Translates the string.
662
     *
663
     * @param string $str           Text to translate or singular form
664
     * @param string $str_plurals   Plurals form string
665
     * @param int $number           Number of items for plurals
666
     * @return string
667
     */
668
    public function translate($str, $str_plurals = null, $number = null)
669
    {
670
        //First, check if current addon has a translation
671
        $translator = self::getTranslator();
672
        $translator->setAddonName($this->addonName);
673
        $translator->setLangPath(null);
674
        $translation = $translator->translate($str, $str_plurals, $number);
675
        
676
        //Then, check if current component has a translation
677
        if ($translation === $str) {
678
            if($currentComponent = $this->getCurrentComponent()){
679
                $translator->setAddonName($currentComponent->getPackageName());
680
                $translator->setLangPath($currentComponent->getLangPath());
681
                $translation = $translator->translate($str, $str_plurals, $number);
682
                
683
            }
684
        }
685
        //Then, check if libapp has a translation
686
        if ($translation === $str) { 
687
            $translator->setLangPath(null);//Reset lang path
688
            $translator->setAddonName('libapp');
689
            $translation = $translator->translate($str, $str_plurals, $number);
690
        }
691
        
692
        return $translation;
693
    }
694
695
    /**
696
     * @param string    $str
697
     * @param string    $str_plurals
698
     * @param int       $number
699
     * @return string
700
     */
701
    public function translatable($str, $str_plurals = null, $number = null)
702
    {
703
        return $str;
704
    }
705
706
    /**
707
     * Translates all the string in an array and returns a new array.
708
     *
709
     * @param array $arr
710
     * @return array
711
     */
712
    public function translateArray($arr)
713
    {
714
        $newarr = $arr;
715
716
        foreach ($newarr as &$str) {
717
            $str = $this->translate($str);
718
        }
719
        return $newarr;
720
    }
721
722
723
724
    /**
725
     * Returns a link for writting an email to the specified email address.
726
     *
727
     * @param string $addr
728
     * @param string $subject
729
     * @param string $body
730
     *
731
     * @return string
732
     */
733
    public function mailTo($addr, $subject = null, $body = null)
734
    {
735
        $mailTo = 'mailto:' . $addr;
736
        $parameters = array();
737
        if (isset($subject)) {
738
            $parameters[] = 'subject=' . $subject;
739
        }
740
        if (isset($body)) {
741
            $parameters[] = 'body=' . $body;
742
        }
743
        if (!empty($parameters)) {
744
            $mailTo .= '?' . implode('&', $parameters);
745
        }
746
747
        return $mailTo;
748
    }
749
750
751
752
    /**
753
     * Format a number for display
754
     *
755
     * @param   float|string|null   $number     Numeric value with decimal
756
     * @return string
757
     */
758
    public function numberFormat($number, $decimals = 2)
759
    {
760
        if (is_null($number)) {
761
            return '#,##';
762
        }
763
764
        $number = number_format(floatval($number), $decimals, ',', ' ');
765
        return str_replace(' ', bab_nbsp(), $number);
766
    }
767
768
769
    /**
770
     * Format a number with an optional unit.
771
     *
772
     * If the value is >= 1000 the value is shortened and the corresponding prexif (k or M) is used.
773
     *
774
     * @param float|string|null $number
775
     * @param string $unitSymbol    (For example $, m2, Wh)
776
     * @param int $decimals
777
     * @return string|mixed
778
     */
779
    public function shortFormatWithUnit($number, $unitSymbol = '', $decimals = 2)
780
    {
781
        if (is_null($number)) {
782
            return '#,##';
783
        }
784
785
        $prefix = '';
786
        if ($number >= 1000000) {
787
            $number /= 1000000;
788
            $prefix = 'M';
789
        } elseif ($number >= 1000) {
790
            $number /= 1000;
791
            $prefix = 'k';
792
        }
793
794
        $number = number_format($number, $decimals, ',', ' ');
0 ignored issues
show
Bug introduced by
It seems like $number can also be of type string; however, parameter $num of number_format() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

794
        $number = number_format(/** @scrutinizer ignore-type */ $number, $decimals, ',', ' ');
Loading history...
795
        return str_replace(' ', bab_nbsp(), $number . ' ' . $prefix . $unitSymbol);
796
    }
797
798
799
    /**
800
     * Reformat a phone number in the specified format.
801
     *
802
     * @param string    $phone      The phone number to be formatted
803
     * @param int       $format     The format the phone number should be formatted into
804
     *
805
     * @return string               The formatted phone number
806
     */
807
    public function phoneNumberFormat($phone, $format = null)
808
    {
809
        $PhoneNumber = \bab_Functionality::get('PhoneNumber');
810
        if ($PhoneNumber === false) {
0 ignored issues
show
introduced by
The condition $PhoneNumber === false is always false.
Loading history...
811
            return $phone;
812
        }
813
814
        if (!isset($format)) {
815
            $format = \bab_registry::get('/' . $this->addonName . '/numberFormat', $PhoneNumber->getDefaultFormat());
0 ignored issues
show
Bug introduced by
The method getDefaultFormat() does not exist on bab_functionality. It seems like you code against a sub-type of bab_functionality such as Capwelton\LibApp\Func_App. ( Ignorable by Annotation )

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

815
            $format = \bab_registry::get('/' . $this->addonName . '/numberFormat', $PhoneNumber->/** @scrutinizer ignore-call */ getDefaultFormat());
Loading history...
816
        }
817
        $phoneNumberUtil = $PhoneNumber->PhoneNumberUtil();
0 ignored issues
show
Bug introduced by
The method PhoneNumberUtil() does not exist on bab_functionality. It seems like you code against a sub-type of bab_functionality such as Capwelton\LibApp\Func_App. ( Ignorable by Annotation )

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

817
        /** @scrutinizer ignore-call */ 
818
        $phoneNumberUtil = $PhoneNumber->PhoneNumberUtil();
Loading history...
818
819
        try {
820
            $phoneNumber = $phoneNumberUtil->parse($phone, 'FR');
821
            $phone = $phoneNumberUtil->format($phoneNumber, $format);
822
        } catch (\libphonenumber\NumberParseException $e) {
0 ignored issues
show
Bug introduced by
The type libphonenumber\NumberParseException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
823
        }
824
825
        return $phone;
826
    }
827
828
829
830
831
    /**
832
     * Includes Controller class definition.
833
     */
834
    public function includeController()
835
    {
836
    }
837
838
839
    /**
840
     * Includes RecordController class definition.
841
     */
842
    public function includeRecordController()
843
    {
844
    }
845
846
847
    /**
848
     * Instanciates the controller.
849
     *
850
     * @return AppController
851
     */
852
    public function Controller()
853
    {
854
        $this->includeController();
855
        return bab_getInstance($this->classPrefix.'Controller')->setApp($this);
856
    }
857
858
859
    /**
860
     * Instanciates a controller class.
861
     *
862
     * @return \bab_Controller
863
     */
864
    public function ControllerProxy($className, $proxy = true)
865
    {
866
        $this->includeController();
867
        if ($proxy) {
868
            return AppController::getProxyInstance($this, $className);
869
        }
870
871
        return new $className($this);
872
    }
873
874
875
876
    /**
877
     * Include class app_Ui
878
     *
879
     */
880
    public function includeUi()
881
    {
882
        // require_once APP_UI_PATH . 'ui.class.php
883
    }
884
885
886
    /**
887
     * The app_Ui object propose an access to all ui files and ui objects (widgets)
888
     *
889
     * @return AppUi
890
     */
891
    public function Ui()
892
    {
893
        if(get_class($this) == "Capwelton\LibApp\Func_App"){
894
            return bab_getInstance("Capwelton\LibApp\Ui\AppUi")->setApp($this);
895
        }else{
896
            return bab_getInstance($this->classPrefix . 'Ui')->setApp($this);
897
        }
898
    }
899
900
    /**
901
     * Get upload path
902
     * if the method return null, no upload functionality
903
     *
904
     * @return \bab_Path
905
     */
906
    public function getUploadPath()
907
    {
908
        require_once $GLOBALS['babInstallPath'].'utilit/path.class.php';
909
        return new \bab_Path(bab_getAddonInfosInstance($this->getAddonName())->getUploadPath());
910
    }
911
912
913
    /**
914
     *
915
     * @param string $name
916
     * @param mixed $arguments
917
     * @return mixed
918
     */
919
    public function __call($name, $arguments)
920
    {
921
        switch (true) {
922
923
            case substr($name, -strlen('SetClassName')) === 'SetClassName':
924
                $className = substr($name, 0, strlen($name) - strlen('SetClassName'));
925
                if($component = $this->getComponentByName($className)){
926
                    return $component->getSetClassName();
927
                }
928
                $setName = $className.'Set';
929
                return $this->classPrefix . $setName;
930
931
            case substr($name, -strlen('ClassName')) === 'ClassName':
932
                $recordName = substr($name, 0, strlen($name) - strlen('ClassName'));
933
                if($component = $this->getComponentByName($recordName)){
934
                    return $component->getRecordClassName();
935
                }
936
                return $this->classPrefix . $recordName;
937
938
            case substr($name, 0, strlen('include')) === 'include' && substr($name, -strlen('Set')) === 'Set':
939
                $fileNameBase = strtolower(substr(substr($name, 0, strlen($name) - strlen('Set')), strlen('include')));
940
                if($this->getComponentByName($fileNameBase)){
941
                    return;
942
                }
943
                $path = APP_SET_PATH . $fileNameBase . '.class.php';
944
                if(is_file($path)){
945
                    require_once $path;
946
                }
947
                return;
948
949
            case substr($name, -strlen('Set')) === 'Set':
950
                if($component = $this->getComponentByName(substr($name, 0, strlen($name) -strlen('Set')))){
951
                    return $component->recordSet();
952
                }
953
 
954
                $includeMethod = 'include' . $name;
955
                $this->$includeMethod();
956
                $setClassNameMethod = $name . 'ClassName';
957
                $className = $this->$setClassNameMethod();
958
                $set = new $className($this);
959
                return $set;
960
            
961
            case ($component = $this->getComponentByName($name)) != false:
962
                return $component;
963
            default:
964
                $setName = $name . 'Set';
965
                $recordClassNameMethod = $name . 'ClassName';
966
                $recordClassName = $this->$recordClassNameMethod();
967
                if (isset($arguments[0])) {
968
                    if ($arguments[0] instanceof $recordClassName) {
969
                        return $arguments[0];
970
                    }
971
                    $set = $this->$setName();
972
                    return $set->get($arguments[0]);
973
                }
974
                return null;
975
        }
976
    }
977
    
978
979
    public function LinkSet(){
980
        return $this->AppLinkSet();
981
    }
982
    public function AppLinkSet(){
983
        return new AppLinkSet($this);
984
    }
985
986
    public function CustomFieldSet(){
987
        return $this->AppCustomFieldSet();
988
    }
989
    public function AppCustomFieldSet(){
990
        return new AppCustomFieldSet($this);
991
    }
992
993
    public function CustomContainerSet(){
994
        return $this->AppCustomContainerSet();
995
    }
996
    public function AppCustomContainerSet(){
997
        return new AppCustomContainerSet($this);
998
    }
999
1000
    public function CustomSectionSet(){
1001
        return $this->AppCustomSectionSet();
1002
    }
1003
    public function AppCustomSectionSet(){
1004
        return new AppCustomSectionSet($this);
1005
    }
1006
1007
    public function LogSet(){
1008
        return $this->AppLogSet();
1009
    }
1010
    public function AppLogSet(){
1011
        return new AppLogSet($this);
1012
    }
1013
1014
1015
1016
    /**
1017
     * Test if this App implementation handles the specified object class.
1018
     *
1019
     * The default is to consider that an object Xxxx implemented if the includeXxxxSet() method is
1020
     * declared public on this App.
1021
     *
1022
     * @param	string	$objectClassName		App object name (eg. 'Contact' or 'CatalogItem')
1023
     * @return bool
1024
     */
1025
    public function __isset($objectClassName)
1026
    {
1027
        if (null === $this->implementedObjects) {
1028
1029
            $this->implementedObjects = array();
0 ignored issues
show
Bug Best Practice introduced by
The property implementedObjects does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
1030
1031
            $className = get_class($this);
1032
            $rClass = new \ReflectionClass($className);
1033
1034
            foreach ($rClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
1035
1036
                // We consider object Xxxx implemented if the includeXxxxSet() method is
1037
                // declared public on this.
1038
1039
                if ($m->getDeclaringClass()->name !== $className) {
1040
                    // The method is declared on an ancestor class.
1041
                    continue;
1042
                }
1043
1044
                if (substr($m->name, 0, 7) === 'include' && substr($m->name, -3) === 'Set') {
1045
                    $this->implementedObjects[substr($m->name, 7, -3)] = 1;
1046
                }
1047
            }
1048
        }
1049
1050
        return isset($this->implementedObjects[$objectClassName]);
1051
    }
1052
    
1053
    /**
1054
     * Returns the current user id.
1055
     *
1056
     * @return string		The current user id	or '' if the user is not logged in.
1057
     */
1058
    public function getCurrentUser()
1059
    {
1060
        return bab_getUserId();
1061
    }
1062
    
1063
    public function isSSEEnabled()
1064
    {
1065
        $registry = app_getRegistry();
1066
        $registry->changeDirectory('configuration');
1067
        $registry->changeDirectory('SSE');
1068
        return $registry->getValue('enabled', false);
1069
    }
1070
    
1071
    public function getLoggedUsers()
1072
    {
1073
        global $babDB;
1074
        $users = array();
1075
        $res = $babDB->db_query("SELECT DISTINCT(id_user) FROM ".BAB_USERS_LOG_TBL." WHERE id_user != 0");
1076
        while (list($id_user) = $babDB->db_fetch_array($res))
1077
        {
1078
            $users[] = $id_user;
1079
        }
1080
        return $users;
1081
    }
1082
    
1083
    /**
1084
     * Get upload path
1085
     * if the method return null, no upload functionality
1086
     *
1087
     * @return \bab_Path
1088
     */
1089
    public function uploadPath()
1090
    {
1091
        require_once $GLOBALS['babInstallPath'].'utilit/path.class.php';
1092
        return new \bab_Path(bab_getAddonInfosInstance($this->getAddonName())->getUploadPath());
1093
    }
1094
    
1095
    /**
1096
     * @see AppSSESet::newBrowserNotification()
1097
     * @param array $data
1098
     * @param mixed $for
1099
     * @return boolean
1100
     */
1101
    public function createBrowserNotification($data, $for = null)
1102
    {
1103
        $sseSet = $this->SSESet();
0 ignored issues
show
Bug introduced by
The method SSESet() does not exist on Capwelton\LibApp\Func_App. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

1103
        /** @scrutinizer ignore-call */ 
1104
        $sseSet = $this->SSESet();
Loading history...
1104
        return $sseSet->newBrowserNotification($data, $for);
1105
    }
1106
    
1107
    /**
1108
     * @see AppSSESet::newReloadSelector()
1109
     * @param string    $data
1110
     * @param mixed     $for
1111
     * @return boolean
1112
     */
1113
    public function createReloadSelector($reloadSelector, $for = null)
1114
    {
1115
        $sseSet = $this->SSESet();
1116
        return $sseSet->newReloadSelector($reloadSelector, $for);
1117
    }
1118
}
1119
1120
if (app_App()) {
1121
    spl_autoload_register(array(app_App(), 'loadObject'));
1122
}
1123