Passed
Push — develop ( 6505d7...4d6557 )
by Andrew
04:42
created

Recipe::getRecipeSeomaticModel()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
nc 3
nop 0
dl 0
loc 11
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * Recipe plugin for Craft CMS 3.x
4
 *
5
 * A comprehensive recipe FieldType for Craft CMS that includes metric/imperial
6
 * conversion, portion calculation, and JSON-LD microdata support
7
 *
8
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
9
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
10
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
11
12
namespace nystudio107\recipe\models;
13
14
use nystudio107\recipe\helpers\Json;
15
use nystudio107\recipe\helpers\PluginTemplate;
16
use nystudio107\seomatic\Seomatic;
0 ignored issues
show
Bug introduced by
The type nystudio107\seomatic\Seomatic 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...
17
use nystudio107\seomatic\models\MetaJsonLd;
0 ignored issues
show
Bug introduced by
The type nystudio107\seomatic\models\MetaJsonLd 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...
18
19
use Craft;
20
use craft\base\Model;
21
use craft\helpers\Template;
22
23
use Twig\Markup;
24
25
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
26
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
27
 * @package   Recipe
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
28
 * @since     1.0.0
0 ignored issues
show
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
29
 */
0 ignored issues
show
Coding Style introduced by
Missing @link tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @category tag in class comment
Loading history...
30
class Recipe extends Model
31
{
32
    // Constants
33
    // =========================================================================
34
35
    const SEOMATIC_PLUGIN_HANDLE = 'seomatic';
36
37
    const US_RDA = [
38
        'calories' => 2000,
39
        'carbohydrateContent' => 275,
40
        'cholesterolContent' => 300,
41
        'fatContent' => 78,
42
        'fiberContent' => 28,
43
        'proteinContent' => 50,
44
        'saturatedFatContent' => 20,
45
        'sodiumContent' => 2300,
46
        'sugarContent' => 50,
47
    ];
48
49
    // Mapping to convert any of the incorrect plural values
50
    const NORMALIZE_PLURALS = [
51
        'tsps' => 'tsp',
52
        'tbsps' => 'tbsp',
53
        'flozs' => 'floz',
54
        'cups' => 'cups',
55
        'ozs' => 'oz',
56
        'lbs' => 'lb',
57
        'mls' => 'ml',
58
        'ls' => 'l',
59
        'mgs' => 'mg',
60
        'gs' => 'g',
61
        'kg' => 'kg',
62
    ];
63
64
    // Public Properties
65
    // =========================================================================
66
67
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
68
     * @var string
69
     */
70
    public $name;
71
72
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
73
     * @var string
74
     */
75
    public $description;
76
77
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
78
     * @var string
79
     */
80
    public $skill = 'intermediate';
81
82
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
83
     * @var int
84
     */
85
    public $serves = 1;
86
87
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
88
     * @var array
89
     */
90
    public $ingredients = [];
91
92
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
93
     * @var array
94
     */
95
    public $directions = [];
96
97
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
98
     * @var int
99
     */
100
    public $imageId = 0;
101
102
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
103
     * @var int
104
     */
105
    public $prepTime;
106
107
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
108
     * @var int
109
     */
110
    public $cookTime;
111
112
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
113
     * @var int
114
     */
115
    public $totalTime;
116
117
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
118
     * @var array
119
     */
120
    public $ratings = [];
121
122
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
123
     * @var string
124
     */
125
    public $servingSize;
126
127
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
128
     * @var int
129
     */
130
    public $calories;
131
132
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
133
     * @var int
134
     */
135
    public $carbohydrateContent;
136
137
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
138
     * @var int
139
     */
140
    public $cholesterolContent;
141
142
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
143
     * @var int
144
     */
145
    public $fatContent;
146
147
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
148
     * @var int
149
     */
150
    public $fiberContent;
151
152
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
153
     * @var int
154
     */
155
    public $proteinContent;
156
157
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
158
     * @var int
159
     */
160
    public $saturatedFatContent;
161
162
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
163
     * @var int
164
     */
165
    public $sodiumContent;
166
167
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
168
     * @var int
169
     */
170
    public $sugarContent;
171
172
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
173
     * @var int
174
     */
175
    public $transFatContent;
176
177
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
178
     * @var int
179
     */
180
    public $unsaturatedFatContent;
181
182
    // Public Methods
183
    // =========================================================================
184
185
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
186
     * @inheritdoc
187
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
188
    public function init()
189
    {
190
        parent::init();
191
        // Fix any of the incorrect plural values
192
        if (!empty($this->ingredients)) {
193
            foreach ($this->ingredients as &$row) {
194
                if (!empty($row['units']) && !empty(self::NORMALIZE_PLURALS[$row['units']])) {
195
                    $row['units'] = self::NORMALIZE_PLURALS[$row['units']];
196
                }
197
            }
198
            unset($row);
199
        }
200
    }
201
202
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
203
     * @inheritdoc
204
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
205
    public function rules()
206
    {
207
        return [
208
            ['name', 'string'],
209
            ['name', 'default', 'value' => ''],
210
            ['description', 'string'],
211
            ['skill', 'string'],
212
            ['serves', 'integer'],
213
            ['imageId', 'integer'],
214
            ['prepTime', 'integer'],
215
            ['cookTime', 'integer'],
216
            ['totalTime', 'integer'],
217
            ['servingSize', 'string'],
218
            ['calories', 'integer'],
219
            ['carbohydrateContent', 'integer'],
220
            ['cholesterolContent', 'integer'],
221
            ['fatContent', 'integer'],
222
            ['fiberContent', 'integer'],
223
            ['proteinContent', 'integer'],
224
            ['saturatedFatContent', 'integer'],
225
            ['sodiumContent', 'integer'],
226
            ['sugarContent', 'integer'],
227
            ['transFatContent', 'integer'],
228
            ['unsaturatedFatContent', 'integer'],
229
        ];
230
    }
231
232
    /**
233
     * Return the JSON-LD Structured Data for this recipe
234
     *
235
     * @return array
236
     */
237
    public function getRecipeJSONLD(): array
238
    {
239
        $recipeJSONLD = [
240
            'context' => 'http://schema.org',
241
            'type' => 'Recipe',
242
            'name' => $this->name,
243
            'image' => $this->getImageUrl(),
244
            'description' => $this->description,
245
            'recipeYield' => $this->serves,
246
            'recipeIngredient' => $this->getIngredients('imperial', 0, false),
247
            'recipeInstructions' => $this->getDirections(false),
248
        ];
249
        $recipeJSONLD = array_filter($recipeJSONLD);
250
251
        $nutrition = [
252
            'type' => 'NutritionInformation',
253
            'servingSize' => $this->servingSize,
254
            'calories' => $this->calories,
255
            'carbohydrateContent' => $this->carbohydrateContent,
256
            'cholesterolContent' => $this->cholesterolContent,
257
            'fatContent' => $this->fatContent,
258
            'fiberContent' => $this->fiberContent,
259
            'proteinContent' => $this->proteinContent,
260
            'saturatedFatContent' => $this->saturatedFatContent,
261
            'sodiumContent' => $this->sodiumContent,
262
            'sugarContent' => $this->sugarContent,
263
            'transFatContent' => $this->transFatContent,
264
            'unsaturatedFatContent' => $this->unsaturatedFatContent,
265
        ];
266
        $nutrition = array_filter($nutrition);
267
        $recipeJSONLD['nutrition'] = $nutrition;
268
        if (count($recipeJSONLD['nutrition']) === 1) {
269
            unset($recipeJSONLD['nutrition']);
270
        }
271
        $aggregateRating = $this->getAggregateRating();
272
        if ($aggregateRating) {
273
            $aggregateRatings = [
274
                'type' => 'AggregateRating',
275
                'ratingCount' => $this->getRatingsCount(),
276
                'bestRating' => '5',
277
                'worstRating' => '1',
278
                'ratingValue' => $aggregateRating,
279
            ];
280
            $aggregateRatings = array_filter($aggregateRatings);
281
            $recipeJSONLD['aggregateRating'] = $aggregateRatings;
282
283
            $reviews = [];
284
            foreach ($this->ratings as $rating) {
285
                $review = [
286
                    'type' => 'Review',
287
                    'author' => $rating['author'],
288
                    'name' => $this->name . ' ' . Craft::t('recipe', 'Review'),
289
                    'description' => $rating['review'],
290
                    'reviewRating' => [
291
                        'type' => 'Rating',
292
                        'bestRating' => '5',
293
                        'worstRating' => '1',
294
                        'ratingValue' => $rating['rating'],
295
                    ],
296
                ];
297
                $reviews[] = $review;
298
            }
299
            $reviews = array_filter($reviews);
300
            $recipeJSONLD['review'] = $reviews;
301
        }
302
303
        if ($this->prepTime) {
304
            $recipeJSONLD['prepTime'] = 'PT' . $this->prepTime . 'M';
305
        }
306
        if ($this->cookTime) {
307
            $recipeJSONLD['cookTime'] = 'PT' . $this->cookTime . 'M';
308
        }
309
        if ($this->totalTime) {
310
            $recipeJSONLD['totalTime'] = 'PT' . $this->totalTime . 'M';
311
        }
312
313
        return $recipeJSONLD;
314
    }
315
316
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $add should have a doc-comment as per coding-style.
Loading history...
317
     * Render the JSON-LD Structured Data for this recipe
318
     *
319
     * @return null|MetaJsonLd
320
     */
321
    public function createRecipeMetaJsonLd(bool $add = true)
322
    {
323
        $result = null;
324
        if (Craft::$app->getPlugins()->getPlugin(self::SEOMATIC_PLUGIN_HANDLE)) {
325
            $seomatic = Seomatic::getInstance();
326
            if ($seomatic !== null) {
327
                $result = Seomatic::$plugin->jsonLd->create(
328
                    $this->getRecipeJSONLD(),
329
                    $add
330
                );
331
            }
332
        }
333
334
        return $result;
335
    }
336
337
    /**
338
     * Render the JSON-LD Structured Data for this recipe
339
     *
340
     * @param bool $raw
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
341
     *
342
     * @return string|\Twig_Markup
343
     */
344
    public function renderRecipeJSONLD($raw = true)
345
    {
346
        return $this->renderJsonLd($this->getRecipeJSONLD(), $raw);
347
    }
348
349
    /**
350
     * Get the URL to the recipe's image
351
     *
352
     * @param null $transform
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Documentation Bug introduced by
Are you sure the doc-type for parameter $transform is correct as it would always require null to be passed?
Loading history...
353
     *
354
     * @return null|string
355
     */
356
    public function getImageUrl($transform = null)
357
    {
358
        $result = '';
359
        if (isset($this->imageId) && $this->imageId) {
360
            $image = Craft::$app->getAssets()->getAssetById($this->imageId[0]);
361
            if ($image) {
362
                $result = $image->getUrl($transform);
363
            }
364
        }
365
366
        return $result;
367
    }
368
369
    /**
370
     * Render the Nutrition Facts template
371
     *
372
     * @param array $rda
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
373
     * @return Markup
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
374
     */
375
    public function renderNutritionFacts(array $rda = self::US_RDA): Markup {
0 ignored issues
show
Coding Style introduced by
Opening brace should be on a new line
Loading history...
376
        return PluginTemplate::renderPluginTemplate(
377
            'recipe-nutrition-facts',
378
            [
379
                'value' => $this,
380
                'rda' => $rda,
381
            ]
382
        );
383
    }
384
385
    /**
386
     * Get all of the ingredients for this recipe
387
     *
388
     * @param string $outputUnits
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
389
     * @param int    $serving
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
390
     * @param bool   $raw
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
391
     *
392
     * @return array
393
     */
394
    public function getIngredients($outputUnits = 'imperial', $serving = 0, $raw = true): array
395
    {
396
        $result = [];
397
398
        if (!empty($this->ingredients)) {
399
            foreach ($this->ingredients as $row) {
400
                $convertedUnits = '';
401
                $ingredient = '';
402
                if ($row['quantity']) {
403
                    // Multiply the quantity by how many servings we want
404
                    $multiplier = 1;
405
                    if ($serving > 0) {
406
                        $multiplier = $serving / $this->serves;
407
                    }
408
                    $quantity = $row['quantity'] * $multiplier;
409
                    $originalQuantity = $quantity;
410
411
                    // Do the imperial->metric units conversion
412
                    if ($outputUnits === 'imperial') {
413
                        switch ($row['units']) {
414
                            case 'ml':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
415
                                $convertedUnits = 'tsp';
416
                                $quantity *= 0.2;
417
                                break;
418
                            case 'l':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
419
                                $convertedUnits = 'cups';
420
                                $quantity *= 4.2;
421
                                break;
422
                            case 'mg':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
423
                                $convertedUnits = 'oz';
424
                                $quantity *= 0.000035274;
425
                                break;
426
                            case 'g':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
427
                                $convertedUnits = 'oz';
428
                                $quantity *= 0.035274;
429
                                break;
430
                            case 'kg':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
431
                                $convertedUnits = 'lb';
432
                                $quantity *= 2.2046226218;
433
                                break;
434
                        }
435
                    }
436
                    // Do the metric->imperial units conversion
437
                    if ($outputUnits === 'metric') {
438
                        switch ($row['units']) {
439
                            case 'tsp':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
440
                                $convertedUnits = 'ml';
441
                                $quantity *= 4.929;
442
                                break;
443
                            case 'tbsp':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
444
                                $convertedUnits = 'ml';
445
                                $quantity *= 14.787;
446
                                break;
447
                            case 'floz':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
448
                                $convertedUnits = 'ml';
449
                                $quantity *= 29.574;
450
                                break;
451
                            case 'cups':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
452
                                $convertedUnits = 'l';
453
                                $quantity *= 0.236588;
454
                                break;
455
                            case 'oz':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
456
                                $convertedUnits = 'g';
457
                                $quantity *= 28.3495;
458
                                break;
459
                            case 'lb':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
460
                                $convertedUnits = 'kg';
461
                                $quantity *= 0.45359237;
462
                                break;
463
                        }
464
465
                        $quantity = round($quantity, 1);
466
                    }
467
468
                    // Convert units to nice fractions
469
                    $quantity = $this->convertToFractions($quantity);
470
471
                    $ingredient .= $quantity;
472
473
                    if ($row['units']) {
474
                        $units = $row['units'];
475
                        if ($convertedUnits) {
476
                            $units = $convertedUnits;
477
                        }
478
                        if ($originalQuantity <= 1) {
479
                            $units = rtrim($units);
480
                            $units = rtrim($units, 's');
481
                        }
482
                        $ingredient .= ' ' . $units;
483
                    }
484
                }
485
                if ($row['ingredient']) {
486
                    $ingredient .= ' ' . $row['ingredient'];
487
                }
488
                if ($raw) {
489
                    $ingredient = Template::raw($ingredient);
490
                }
491
                $result[] = $ingredient;
492
            }
493
        }
494
495
        return $result;
496
    }
497
498
    /**
499
     * Convert decimal numbers into fractions
500
     *
501
     * @param $quantity
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
502
     *
503
     * @return string
504
     */
505
    private function convertToFractions($quantity)
0 ignored issues
show
Coding Style introduced by
Private method name "Recipe::convertToFractions" must be prefixed with an underscore
Loading history...
506
    {
507
        $whole = floor($quantity);
508
        // Round the mantissa so we can do a floating point comparison without
509
        // weirdness, per: https://www.php.net/manual/en/language.types.float.php#113703
510
        $fraction = round($quantity - $whole, 3);
511
        switch ($fraction) {
512
            case 0:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
513
                $fraction = '';
514
                break;
515
            case 0.25:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
516
                $fraction = ' &frac14;';
517
                break;
518
            case 0.33:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
519
                $fraction = ' &frac13;';
520
                break;
521
            case 0.66:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
522
                $fraction = ' &frac23;';
523
                break;
524
            case 0.165:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
525
                $fraction = ' &frac16;';
526
                break;
527
            case 0.5:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
528
                $fraction = ' &frac12;';
529
                break;
530
            case 0.75:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
531
                $fraction = ' &frac34;';
532
                break;
533
            case 0.125:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
534
                $fraction = ' &#x215B;';
535
                break;
536
            case 0.375:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
537
                $fraction = ' &#x215C;';
538
                break;
539
            case 0.625:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
540
                $fraction = ' &#x215D;';
541
                break;
542
            case 0.875:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
543
                $fraction = ' &#x215E;';
544
                break;
545
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
546
                $precision = 1;
547
                $pnum = round($fraction, $precision);
548
                $denominator = 10 ** $precision;
549
                $numerator = $pnum * $denominator;
550
                $fraction = ' <sup>'
551
                    .$numerator
552
                    . '</sup>&frasl;<sub>'
553
                    .$denominator
554
                    . '</sub>';
555
                break;
556
        }
557
        if ($whole == 0) {
558
            $whole = '';
559
        }
560
561
        return $whole.$fraction;
562
    }
563
564
    /**
565
     * Get all of the directions for this recipe
566
     *
567
     * @param bool $raw
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
568
     *
569
     * @return array
570
     */
571
    public function getDirections($raw = true)
572
    {
573
        $result = [];
574
        if (!empty($this->directions)) {
575
            foreach ($this->directions as $row) {
576
                $direction = $row['direction'];
577
                if ($raw) {
578
                    $direction = Template::raw($direction);
579
                }
580
                $result[] = $direction;
581
            }
582
        }
583
584
        return $result;
585
    }
586
587
    /**
588
     * Get the aggregate rating from all of the ratings
589
     *
590
     * @return float|int|string
591
     */
592
    public function getAggregateRating()
593
    {
594
        $result = 0;
595
        $total = 0;
596
        if (isset($this->ratings) && !empty($this->ratings)) {
597
            foreach ($this->ratings as $row) {
598
                $result += $row['rating'];
599
                $total++;
600
            }
601
            $result /= $total;
602
        } else {
603
            $result = '';
604
        }
605
606
        return $result;
607
    }
608
609
    /**
610
     * Get the total number of ratings
611
     *
612
     * @return int
613
     */
614
    public function getRatingsCount(): int
615
    {
616
        return count($this->ratings);
617
    }
618
619
    // Private Methods
620
    // =========================================================================
621
622
    /**
623
     * Renders a JSON-LD representation of the schema
624
     *
625
     * @param      $json
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 1 spaces but found 6
Loading history...
626
     * @param bool $raw
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
627
     *
628
     * @return string|\Twig_Markup
629
     */
630
    private function renderJsonLd($json, $raw = true)
0 ignored issues
show
Coding Style introduced by
Private method name "Recipe::renderJsonLd" must be prefixed with an underscore
Loading history...
631
    {
632
        $linebreak = '';
633
634
        // If `devMode` is enabled, make the JSON-LD human-readable
635
        if (Craft::$app->getConfig()->getGeneral()->devMode) {
636
            $linebreak = PHP_EOL;
637
        }
638
639
        // Render the resulting JSON-LD
640
        $result = '<script type="application/ld+json">'
641
            .$linebreak
642
            .Json::encode($json)
643
            .$linebreak
644
            .'</script>';
645
646
        if ($raw === true) {
647
            $result = Template::raw($result);
648
        }
649
650
        return $result;
651
    }
652
}
653