Completed
Push — master ( 4c2fab...6ca203 )
by Dan
03:07
created

BuildFromUrlCommand::getColorGenerator()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 24
rs 8.5125
cc 6
eloc 14
nc 6
nop 3
1
<?php
2
3
namespace SixtyNine\Cloud\Command;
4
5
use Imagine\Image\ImageInterface;
6
use SixtyNine\Cloud\Builder\CloudBuilder;
7
use SixtyNine\Cloud\Builder\FiltersBuilder;
8
use SixtyNine\Cloud\Builder\WordsListBuilder;
9
use SixtyNine\Cloud\Factory\FontsFactory;
10
use SixtyNine\Cloud\Factory\PlacerFactory;
11
use SixtyNine\Cloud\Placer\PlacerInterface;
12
use SixtyNine\Cloud\Renderer\CloudRenderer;
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Input\InputArgument;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Input\InputOption;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
class BuildFromUrlCommand extends Command
20
{
21
    protected function configure()
22
    {
23
        $this
24
            ->setName('cloud:from-url')
25
            ->setDescription('Create a cloud from a URL')
26
            ->addArgument('url', InputArgument::REQUIRED, 'The URL for the words')
27
            // Filters options
28
            ->addOption('case', null, InputOption::VALUE_OPTIONAL, 'Change case filter type (uppercase, lowercase, ucfirst)')
29
            ->addOption('max-word-count', null, InputOption::VALUE_OPTIONAL, 'Maximum number of words', 100)
30
            ->addOption('min-word-length', null, InputOption::VALUE_OPTIONAL, 'Minimumal word length', 5)
31
            ->addOption('max-word-length', null, InputOption::VALUE_OPTIONAL, 'Maximal word length', 10)
32
            ->addOption('no-remove-numbers', null, InputOption::VALUE_NONE, 'Disable the remove numbers filter')
33
            ->addOption('no-remove-trailing', null, InputOption::VALUE_NONE, 'Disable the remove trailing characters filter')
34
            ->addOption('no-remove-unwanted', null, InputOption::VALUE_NONE, 'Disable the remove unwanted characters filter')
35
            // WordsList options
36
            ->addOption('vertical-probability', null, InputOption::VALUE_OPTIONAL, 'The percentage probability of having vertical words (0-100)', 50)
37
            ->addOption('palette', null, InputOption::VALUE_OPTIONAL, 'The name of the palette used to color words')
38
            ->addOption('palette-type', null, InputOption::VALUE_OPTIONAL, 'The way the palette colors are used (cycle, random)', 'cycle')
39
            ->addOption('palettes-file', null, InputOption::VALUE_OPTIONAL, 'Optional path to the fonts, if omitted, defaults to <base>/fonts')
40
            ->addOption('sort-by', null, InputOption::VALUE_OPTIONAL, 'Words sorting field (text, count, angle)')
41
            ->addOption('sort-order', null, InputOption::VALUE_OPTIONAL, 'Words sorting order (asc, desc)')
42
            // Cloud options
43
            ->addOption('background-color', null, InputOption::VALUE_OPTIONAL, 'Background color of the cloud', '#FFFFFF')
44
            ->addOption('placer', null, InputOption::VALUE_OPTIONAL, 'Word placer to use')
45
            ->addOption('font', null, InputOption::VALUE_OPTIONAL, 'Font to use to draw the cloud')
46
            ->addOption('width', null, InputOption::VALUE_OPTIONAL, 'Width of the cloud', 800)
47
            ->addOption('height', null, InputOption::VALUE_OPTIONAL, 'Height of the cloud', 600)
48
            ->addOption('font-size-boost', null, InputOption::VALUE_OPTIONAL, 'Minimal font size (linear, dim, boost)', 'linear')
49
            ->addOption('min-font-size', null, InputOption::VALUE_OPTIONAL, 'Minimal font size', 12)
50
            ->addOption('max-font-size', null, InputOption::VALUE_OPTIONAL, 'Maximal font size', 64)
51
            // Other options
52
            ->addOption('save-to-file', null, InputOption::VALUE_OPTIONAL, 'If set to a file name, the output will be saved there')
53
            ->addOption('format', null, InputOption::VALUE_OPTIONAL, 'Output format (gif, jpeg, png)', 'png')
54
            ->addOption('fonts-path', null, InputOption::VALUE_OPTIONAL, 'Optional path to the fonts, if omitted, defaults to <base>/fonts')
55
            ->addOption('render-usher', null, InputOption::VALUE_NONE, 'Enable the rendering of the words usher')
56
            ->addOption('render-boxes', null, InputOption::VALUE_NONE, 'Enable the rendering of the words bounding boxes')
57
        ;
58
    }
59
60
    protected function execute(InputInterface $input, OutputInterface $output)
61
    {
62
        $helper = new CommandsHelper();
63
64
        // Build the filters
65
        $filtersBuilder = FiltersBuilder::create()
66
            ->setMinLength($input->getOption('min-word-length'))
67
            ->setMaxLength($input->getOption('max-word-length'))
68
            ->setRemoveNumbers(!$input->getOption('no-remove-numbers'))
69
            ->setRemoveUnwanted(!$input->getOption('no-remove-unwanted'))
70
            ->setRemoveTrailing(!$input->getOption('no-remove-trailing'))
71
        ;
72
73
        $case = $input->getOption('case');
74
        if ($case && in_array($case, $filtersBuilder->getAllowedCase())) {
75
            $filtersBuilder->setCase($case);
76
        }
77
78
        // Create a placer
79
        $placerName = $helper->getPlacer($input->getOption('placer'));
80
        $placer = PlacerFactory::getInstance()->getPlacer(
81
            $placerName,
82
            $input->getOption('width'),
83
            $input->getOption('height')
84
        );
85
86
        // Get the font file
87
        $fontsPath = $input->getOption('fonts-path')
88
            ? realpath($input->getOption('fonts-path'))
89
            : constant('BASE_PATH') . '/fonts'
90
        ;
91
        $factory = FontsFactory::create($fontsPath);
92
        $font = $helper->getFont($factory, $input->getOption('font'));
93
94
        // Create the list builder
95
        $listBuilder = WordsListBuilder::create()
96
            ->setMaxWords($input->getOption('max-word-count'))
97
            ->setFilters($filtersBuilder->build())
98
            ->randomizeOrientation($input->getOption('vertical-probability'))
99
            ->importUrl($input->getArgument('url'))
100
        ;
101
102
        $sortBy = $input->getOption('sort-by');
103
        $sortOrder = $input->getOption('sort-order');
104
105
        if ($sortBy && $sortOrder) {
106
            $listBuilder->sort($sortBy, $sortOrder);
107
        }
108
109
        // Apply a color generator if needed
110
        $colorGenerator = $helper->getColorGenerator(
111
            $input->getOption('palette'),
112
            $input->getOption('palette-type'),
113
            $input->getOption('palettes-file')
114
        );
115
116
        if ($colorGenerator) {
117
            $listBuilder->randomizeColors($colorGenerator);
118
        }
119
120
        // Build the list
121
        $list = $listBuilder->build('list');
122
123
        // Create a cloud builder
124
        $cloudBuilder = CloudBuilder::create($factory)
125
            ->setBackgroundColor($input->getOption('background-color'))
126
            ->setDimension($input->getOption('width'), $input->getOption('height'))
127
            ->setFont($font)
128
            ->setFontSizes($input->getOption('min-font-size'), $input->getOption('max-font-size'))
129
            ->setPlacer($placerName)
130
            ->setSizeGenerator($helper->getFontSizeGenerator($input->getOption('font-size-boost')))
131
            ->useList($list)
132
        ;
133
134
        // Render the cloud and show the bounding boxes and the usher if needed
135
        $image = $this->render(
136
            $cloudBuilder,
137
            $factory,
138
            $input->getOption('render-usher') ? $placer : null,
0 ignored issues
show
Bug introduced by
It seems like $input->getOption('rende...sher') ? $placer : null can also be of type object; however, SixtyNine\Cloud\Command\...romUrlCommand::render() does only seem to accept null|object<SixtyNine\Cl...Placer\PlacerInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
139
            $input->getOption('render-boxes')
140
        );
141
142
        $helper->output($image, $input->getOption('format'), $input->getOption('save-to-file'));
143
    }
144
145
    /**
146
     * @param CloudBuilder $cloudBuilder
147
     * @param FontsFactory $factory
148
     * @param PlacerInterface $placer
149
     * @param bool $renderBoxes
150
     * @return \Imagine\Gd\Image|ImageInterface
151
     */
152
    protected function render(CloudBuilder $cloudBuilder, FontsFactory $factory, PlacerInterface $placer = null, $renderBoxes = false)
153
    {
154
        $renderer = new CloudRenderer();
155
        $image = $renderer->render($cloudBuilder->build(), $factory, $renderBoxes);
156
157
        if ($placer) {
158
            $renderer->renderUsher($image, $placer, '#FF0000');
159
        }
160
161
        return $image;
162
    }
163
}
164