ApplicationConfig::getStyleSet()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
3
/*
4
 * This file is part of the webmozart/console package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Console\Api\Config;
13
14
use Symfony\Component\EventDispatcher\EventDispatcher;
15
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
16
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17
use Webmozart\Assert\Assert;
18
use Webmozart\Console\Api\Command\NoSuchCommandException;
19
use Webmozart\Console\Api\Formatter\Style;
20
use Webmozart\Console\Api\Formatter\StyleSet;
21
use Webmozart\Console\Api\Resolver\CommandResolver;
22
use Webmozart\Console\Formatter\DefaultStyleSet;
23
use Webmozart\Console\Resolver\DefaultResolver;
24
25
/**
26
 * The configuration of a console application.
27
 *
28
 * @since  1.0
29
 *
30
 * @author Bernhard Schussek <[email protected]>
31
 */
32
class ApplicationConfig extends Config
33
{
34
    /**
35
     * @var string
36
     */
37
    private $name;
38
39
    /**
40
     * @var string
41
     */
42
    private $displayName;
43
44
    /**
45
     * @var string
46
     */
47
    private $version;
48
49
    /**
50
     * @var string
51
     */
52
    private $help;
53
54
    /**
55
     * @var CommandConfig[]
56
     */
57
    private $commandConfigs = array();
58
59
    /**
60
     * @var EventDispatcherInterface
61
     */
62
    private $dispatcher;
63
64
    /**
65
     * @var bool
66
     */
67
    private $catchExceptions = true;
68
69
    /**
70
     * @var bool
71
     */
72
    private $terminateAfterRun = true;
73
74
    /**
75
     * @var CommandResolver
76
     */
77
    private $commandResolver;
78
79
    /**
80
     * @var callable
81
     */
82
    private $ioFactory;
83
84
    /**
85
     * @var bool
86
     */
87
    private $debug = false;
88
89
    /**
90
     * @var StyleSet
91
     */
92
    private $styleSet;
93
94
    /**
95
     * Creates a new console application.
96
     *
97
     * @param string $name    The name of the application.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
98
     * @param string $version The application version.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $version not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
99
     *
100
     * @return static The created instance.
101
     */
102 75
    public static function create($name = null, $version = null)
103
    {
104 75
        return new static($name, $version);
105
    }
106
107
    /**
108
     * Creates a new console application.
109
     *
110
     * @param string $name    The name of the application.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
111
     * @param string $version The application version.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $version not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
112
     */
113 320
    public function __construct($name = null, $version = null)
114
    {
115 320
        $this->name = $name;
116 320
        $this->version = $version;
117
118 320
        parent::__construct();
119 320
    }
120
121
    /**
122
     * Returns the name of the application.
123
     *
124
     * @return string The application name.
125
     *
126
     * @see setName()
127
     */
128 60
    public function getName()
129
    {
130 60
        return $this->name;
131
    }
132
133
    /**
134
     * Sets the name of the application.
135
     *
136
     * @param string $name The application name.
137
     *
138
     * @return static The current instance.
139
     *
140
     * @see getName()
141
     */
142 68
    public function setName($name)
143
    {
144 68
        if (null !== $name) {
145 68
            Assert::string($name, 'The application name must be a string. Got: %s');
146 67
            Assert::notEmpty($name, 'The application name must not be empty.');
147 66
            Assert::regex($name, '~^[a-zA-Z0-9\-]+$~', 'The application name must contain letters, numbers and hyphens only. Did you mean to call setDisplayName()?');
148
        }
149
150 65
        $this->name = $name;
151
152 65
        return $this;
153
    }
154
155
    /**
156
     * Returns the application name as it is displayed in the help.
157
     *
158
     * If no display name is set with {@link setDisplayName()}, the humanized
159
     * application name is returned.
160
     *
161
     * @return string The display name.
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
162
     *
163
     * @see setDisplayName()
164
     */
165 43
    public function getDisplayName()
166
    {
167 43
        return $this->displayName ?: $this->getDefaultDisplayName();
168
    }
169
170
    /**
171
     * Sets the application name as it is displayed in the help.
172
     *
173
     * @param string $displayName The display name.
174
     *
175
     * @return static The current instance.
176
     *
177
     * @see getDisplayName()
178
     */
179 57
    public function setDisplayName($displayName)
180
    {
181 57
        if (null !== $displayName) {
182 57
            Assert::string($displayName, 'The display name must be a string. Got: %s');
183 56
            Assert::notEmpty($displayName, 'The display name must not be empty.');
184
        }
185
186 55
        $this->displayName = $displayName;
187
188 55
        return $this;
189
    }
190
191
    /**
192
     * Returns the version of the application.
193
     *
194
     * @return string The application version.
195
     */
196 35
    public function getVersion()
197
    {
198 35
        return $this->version;
199
    }
200
201
    /**
202
     * Sets the version of the application.
203
     *
204
     * @param string $version The application version.
205
     *
206
     * @return static The current instance.
207
     */
208 55
    public function setVersion($version)
209
    {
210 55
        if (null !== $version) {
211 55
            Assert::string($version, 'The application version must be a string. Got: %s');
212 54
            Assert::notEmpty($version, 'The application version must not be empty.');
213
        }
214
215 53
        $this->version = $version;
216
217 53
        return $this;
218
    }
219
220
    /**
221
     * Returns the help text of the application.
222
     *
223
     * @return string The help text.
224
     */
225 21
    public function getHelp()
226
    {
227 21
        return $this->help;
228
    }
229
230
    /**
231
     * Sets the help text of the application.
232
     *
233
     * @param string $help The help text.
234
     *
235
     * @return static The current instance.
236
     */
237 5 View Code Duplication
    public function setHelp($help)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
238
    {
239 5
        if (null !== $help) {
240 5
            Assert::string($help, 'The help text must be a string. Got: %s');
241 4
            Assert::notEmpty($help, 'The help text must not be empty.');
242
        }
243
244 3
        $this->help = $help;
245
246 3
        return $this;
247
    }
248
249
    /**
250
     * Returns the event dispatcher used to dispatch the console events.
251
     *
252
     * @return EventDispatcherInterface The event dispatcher.
253
     */
254 148
    public function getEventDispatcher()
255
    {
256 148
        return $this->dispatcher;
257
    }
258
259
    /**
260
     * Sets the event dispatcher for dispatching the console events.
261
     *
262
     * @param EventDispatcherInterface $dispatcher The event dispatcher.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $dispatcher not be null|EventDispatcherInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
263
     *
264
     * @return static The current instance.
265
     */
266 5
    public function setEventDispatcher(EventDispatcherInterface $dispatcher = null)
267
    {
268 5
        $this->dispatcher = $dispatcher;
269
270 5
        return $this;
271
    }
272
273
    /**
274
     * Adds a listener for the given event name.
275
     *
276
     * See {@link ConsoleEvents} for the supported event names.
277
     *
278
     * @param string   $eventName The event to listen to.
279
     * @param callable $listener  The callback to execute when the event is
280
     *                            dispatched.
281
     * @param int      $priority  The event priority.
282
     *
283
     * @return static The current instance.
284
     *
285
     * @see EventDispatcherInterface::addListener()
286
     */
287 82
    public function addEventListener($eventName, $listener, $priority = 0)
288
    {
289 82
        if (!$this->dispatcher) {
290 81
            $this->dispatcher = new EventDispatcher();
291
        }
292
293 82
        $this->dispatcher->addListener($eventName, $listener, $priority);
294
295 82
        return $this;
296
    }
297
298
    /**
299
     * Adds an event subscriber to the dispatcher.
300
     *
301
     * @param EventSubscriberInterface $subscriber The subscriber to add.
302
     *
303
     * @return static The current instance.
304
     *
305
     * @see EventDispatcherInterface::addSubscriber()
306
     */
307 1 View Code Duplication
    public function addEventSubscriber(EventSubscriberInterface $subscriber)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
    {
309 1
        if (!$this->dispatcher) {
310
            $this->dispatcher = new EventDispatcher();
311
        }
312
313 1
        $this->dispatcher->addSubscriber($subscriber);
314
315 1
        return $this;
316
    }
317
318
    /**
319
     * Removes an event listener for the given event name.
320
     *
321
     * @param string   $eventName The event name.
322
     * @param callable $listener  The callback to remove.
323
     *
324
     * @return static The current instance.
325
     *
326
     * @see EventDispatcherInterface::removeListener()
327
     */
328 1
    public function removeEventListener($eventName, $listener)
329
    {
330 1
        if (!$this->dispatcher) {
331
            $this->dispatcher = new EventDispatcher();
332
        }
333
334 1
        $this->dispatcher->removeListener($eventName, $listener);
335
336 1
        return $this;
337
    }
338
339
    /**
340
     * Removes an event subscriber from the dispatcher.
341
     *
342
     * @param EventSubscriberInterface $subscriber The subscriber to remove.
343
     *
344
     * @return static The current instance.
345
     *
346
     * @see EventDispatcherInterface::removeSubscriber()
347
     */
348 1 View Code Duplication
    public function removeEventSubscriber(EventSubscriberInterface $subscriber)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
349
    {
350 1
        if (!$this->dispatcher) {
351
            $this->dispatcher = new EventDispatcher();
352
        }
353
354 1
        $this->dispatcher->removeSubscriber($subscriber);
355
356 1
        return $this;
357
    }
358
359
    /**
360
     * Returns whether the application catches and displays exceptions thrown
361
     * while running a command.
362
     *
363
     * @return bool Returns `true` if exceptions are caught and `false`
364
     *              otherwise.
365
     *
366
     * @see setCatchExceptions()
367
     */
368 23
    public function isExceptionCaught()
369
    {
370 23
        return $this->catchExceptions;
371
    }
372
373
    /**
374
     * Sets whether the application catches and displays exceptions thrown
375
     * while running a command.
376
     *
377
     * @param bool $catch Whether to catch and display exceptions thrown
378
     *                    while running a command.
379
     *
380
     * @return static The current instance.
381
     *
382
     * @see isExceptionCaught()
383
     */
384 67
    public function setCatchExceptions($catch)
385
    {
386 67
        Assert::boolean($catch);
387
388 65
        $this->catchExceptions = $catch;
389
390 65
        return $this;
391
    }
392
393
    /**
394
     * Returns whether the PHP process is terminated after running a command.
395
     *
396
     * @return bool Returns `true` if the PHP process is terminated after
397
     *              {@link run()} and `false` otherwise.
398
     *
399
     * @see setTerminateAfterRun()
400
     */
401 56
    public function isTerminatedAfterRun()
402
    {
403 56
        return $this->terminateAfterRun;
404
    }
405
406
    /**
407
     * Sets whether to terminate the PHP process after running a command.
408
     *
409
     * @param bool $terminate Whether to terminate the PHP process after
410
     *                        running a command.
411
     *
412
     * @return static The current instance.
413
     *
414
     * @see isTerminatedAfterRun()
415
     */
416 67
    public function setTerminateAfterRun($terminate)
417
    {
418 67
        Assert::boolean($terminate);
419
420 65
        $this->terminateAfterRun = $terminate;
421
422 65
        return $this;
423
    }
424
425
    /**
426
     * Returns the used command resolver.
427
     *
428
     * @return CommandResolver The command resolver.
429
     *
430
     * @see setCommandResolver()
431
     */
432 36
    public function getCommandResolver()
433
    {
434 36
        if (!$this->commandResolver) {
435 34
            $this->commandResolver = new DefaultResolver();
436
        }
437
438 36
        return $this->commandResolver;
439
    }
440
441
    /**
442
     * Sets the used command resolver.
443
     *
444
     * @param CommandResolver $commandResolver The command resolver.
445
     *
446
     * @return static The current instance.
447
     *
448
     * @see getCommandResolver()
449
     */
450 3
    public function setCommandResolver(CommandResolver $commandResolver)
451
    {
452 3
        $this->commandResolver = $commandResolver;
453
454 3
        return $this;
455
    }
456
457
    /**
458
     * Returns the callable used to create {@link IO} instances.
459
     *
460
     * @return callable The callable or `null` if none was set.
461
     *
462
     * @see setIOFactory()
463
     */
464 45
    public function getIOFactory()
465
    {
466 45
        return $this->ioFactory;
467
    }
468
469
    /**
470
     * Sets the callable used to create {@link IO} instances.
471
     *
472
     * The callable receives four arguments:
473
     *
474
     *  * {@link RawArgs}: The raw console arguments.
475
     *  * {@link Input}: The input.
476
     *  * {@link Output}: The output.
477
     *  * {@link Output}: The error output.
478
     *
479
     * The input and output instances may be `null` if none were passed to
480
     * {@link Application::run()}.
481
     *
482
     * @param callable $ioFactory The {@link IO} factory callable.
483
     *
484
     * @return static The current instance.
485
     */
486 114
    public function setIOFactory($ioFactory)
487
    {
488 114
        Assert::nullOrIsCallable($ioFactory, 'The IO factory must be a callable or null. Got: %s');
489
490 113
        $this->ioFactory = $ioFactory;
491
492 113
        return $this;
493
    }
494
495
    /**
496
     * Returns whether the application is in debug mode.
497
     *
498
     * In debug mode, the verbosity is always {@link IO::DEBUG}.
499
     *
500
     * @return bool Returns `true` if the application is in debug mode.
501
     *
502
     * @see setDebug()
503
     */
504 31
    public function isDebug()
505
    {
506 31
        return $this->debug;
507
    }
508
509
    /**
510
     * Sets whether the application is in debug mode.
511
     *
512
     * In debug mode, the verbosity is always {@link IO::DEBUG}.
513
     *
514
     * @param bool $debug Set to `true` to activate the debug mode.
515
     *
516
     * @return static The current instance.
517
     *
518
     * @see isDebug()
519
     */
520 2
    public function setDebug($debug)
521
    {
522 2
        Assert::boolean($debug);
523
524 2
        $this->debug = $debug;
525
526 2
        return $this;
527
    }
528
529
    /**
530
     * Returns the configured style set.
531
     *
532
     * @return StyleSet The style set.
533
     *
534
     * @see setStyleSet()
535
     */
536 36
    public function getStyleSet()
537
    {
538 36
        if (!$this->styleSet) {
539 31
            $this->styleSet = new DefaultStyleSet();
540
        }
541
542 36
        return $this->styleSet;
543
    }
544
545
    /**
546
     * Sets the used style set.
547
     *
548
     * @param StyleSet $styleSet The style set to use.
549
     *
550
     * @return static The current instance.
551
     *
552
     * @see getStyleSet()
553
     */
554 2
    public function setStyleSet(StyleSet $styleSet)
555
    {
556 2
        $this->styleSet = $styleSet;
557
558 2
        return $this;
559
    }
560
561
    /**
562
     * Adds a style to the style set.
563
     *
564
     * @param Style $style The style to add.
565
     *
566
     * @return static The current instance.
567
     *
568
     * @see StyleSet::add()
569
     */
570 1
    public function addStyle(Style $style)
571
    {
572 1
        if (!$this->styleSet) {
573 1
            $this->styleSet = new DefaultStyleSet();
574
        }
575
576 1
        $this->styleSet->add($style);
577
578 1
        return $this;
579
    }
580
581
    /**
582
     * Adds multiple styles to the style set.
583
     *
584
     * @param Style[] $styles The styles to add.
585
     *
586
     * @return static The current instance.
587
     *
588
     * @see StyleSet::merge()
589
     */
590 2
    public function addStyles(array $styles)
591
    {
592 2
        if (!$this->styleSet) {
593 2
            $this->styleSet = new DefaultStyleSet();
594
        }
595
596 2
        $this->styleSet->merge($styles);
597
598 2
        return $this;
599
    }
600
601
    /**
602
     * Removes a style from the style set.
603
     *
604
     * @param string $tag The tag of the style to remove.
605
     *
606
     * @return static The current instance.
607
     *
608
     * @see StyleSet::remove()
609
     */
610 1
    public function removeStyle($tag)
611
    {
612 1
        if ($this->styleSet) {
613 1
            $this->styleSet->remove($tag);
614
        }
615
616 1
        return $this;
617
    }
618
619
    /**
620
     * Starts a configuration block for a command.
621
     *
622
     * The configuration of the command is returned by this method. You can use
623
     * the fluent interface to configure the sub-command before jumping back to
624
     * this configuration with {@link CommandConfig::end()}:
625
     *
626
     * ```php
627
     * protected function configure()
628
     * {
629
     *     $this
630
     *         ->setName('server')
631
     *         ->setDescription('List and manage servers')
632
     *
633
     *         ->beginCommand('add')
634
     *             ->setDescription('Add a server')
635
     *             ->addArgument('host', Argument::REQUIRED)
636
     *             ->addOption('port', 'p', Option::VALUE_OPTIONAL, null, 80)
637
     *         ->end()
638
     *
639
     *         // ...
640
     *     ;
641
     * }
642
     * ```
643
     *
644
     * @param string $name The name of the command.
645
     *
646
     * @return CommandConfig The command configuration.
647
     *
648
     * @see editCommand()
649
     */
650 109
    public function beginCommand($name)
651
    {
652 109
        $commandConfig = new CommandConfig($name, $this);
653
654
        // The name is dynamic, so don't store by name
655 109
        $this->commandConfigs[] = $commandConfig;
656
657 109
        return $commandConfig;
658
    }
659
660
    /**
661
     * Alias for {@link getCommandConfig()}.
662
     *
663
     * This method can be used to nicely edit a command inherited from a
664
     * parent configuration using the fluent API:
665
     *
666
     * ```php
667
     * protected function configure()
668
     * {
669
     *     parent::configure();
670
     *
671
     *     $this
672
     *         ->editCommand('add')
673
     *             // ...
674
     *         ->end()
675
     *
676
     *         // ...
677
     *     ;
678
     * }
679
     * ```
680
     *
681
     * @param string $name The name of the command to edit.
682
     *
683
     * @return CommandConfig The command configuration.
684
     *
685
     * @see beginCommand()
686
     */
687 1
    public function editCommand($name)
688
    {
689 1
        return $this->getCommandConfig($name);
690
    }
691
692
    /**
693
     * Adds a command configuration to the application.
694
     *
695
     * @param CommandConfig $config The command configuration.
696
     *
697
     * @return static The current instance.
698
     *
699
     * @see beginCommand()
700
     */
701 20
    public function addCommandConfig(CommandConfig $config)
702
    {
703
        // The name is dynamic, so don't store by name
704 20
        $this->commandConfigs[] = $config;
705
706 20
        return $this;
707
    }
708
709
    /**
710
     * Adds command configurations to the application.
711
     *
712
     * @param CommandConfig[] $configs The command configurations.
713
     *
714
     * @return static The current instance.
715
     *
716
     * @see beginCommand()
717
     */
718 2
    public function addCommandConfigs(array $configs)
719
    {
720 2
        foreach ($configs as $command) {
721 2
            $this->addCommandConfig($command);
722
        }
723
724 2
        return $this;
725
    }
726
727
    /**
728
     * Sets the command configurations of the application.
729
     *
730
     * @param CommandConfig[] $configs The command configurations.
731
     *
732
     * @return static The current instance.
733
     *
734
     * @see beginCommand()
735
     */
736 1
    public function setCommandConfigs(array $configs)
737
    {
738 1
        $this->commandConfigs = array();
739
740 1
        $this->addCommandConfigs($configs);
741
742 1
        return $this;
743
    }
744
745
    /**
746
     * Returns the command configuration for a given name.
747
     *
748
     * @param string $name The name of the command.
749
     *
750
     * @return CommandConfig The command configuration.
751
     *
752
     * @throws NoSuchCommandException If the command configuration is not found.
753
     *
754
     * @see beginCommand()
755
     */
756 3
    public function getCommandConfig($name)
757
    {
758 3
        foreach ($this->commandConfigs as $commandConfig) {
759 2
            if ($name === $commandConfig->getName()) {
760 2
                return $commandConfig;
761
            }
762
        }
763
764 1
        throw NoSuchCommandException::forCommandName($name);
765
    }
766
767
    /**
768
     * Returns all registered command configurations.
769
     *
770
     * @return CommandConfig[] The command configurations.
771
     *
772
     * @see beginCommand()
773
     */
774 143
    public function getCommandConfigs()
775
    {
776 143
        return $this->commandConfigs;
777
    }
778
779
    /**
780
     * Returns whether the application has a command with a given name.
781
     *
782
     * @param string $name The name of the command.
783
     *
784
     * @return bool Returns `true` if the command configuration with the given
785
     *              name exists and `false` otherwise.
786
     *
787
     * @see beginCommand()
788
     */
789 1
    public function hasCommandConfig($name)
790
    {
791 1
        foreach ($this->commandConfigs as $commandConfig) {
792 1
            if ($name === $commandConfig->getName()) {
793 1
                return true;
794
            }
795
        }
796
797 1
        return false;
798
    }
799
800
    /**
801
     * Returns whether the application has any registered command configurations.
802
     *
803
     * @return bool Returns `true` if command configurations were added to the
804
     *              application and `false` otherwise.
805
     *
806
     * @see beginCommand()
807
     */
808 1
    public function hasCommandConfigs()
809
    {
810 1
        return count($this->commandConfigs) > 0;
811
    }
812
813
    /**
814
     * Returns the default display name used if no display name is set.
815
     *
816
     * @return string The default display name.
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
817
     */
818 18
    protected function getDefaultDisplayName()
819
    {
820 18
        if (!$this->name) {
821 16
            return null;
822
        }
823
824 2
        return ucwords(preg_replace('~[\s-_]+~', ' ', $this->name));
825
    }
826
}
827