Passed
Push — master ( d878f0...92c484 )
by Stefan
07:20
created

JsonLDLocalBusiness::setAdress()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 5
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\JsonLD;
5
6
/**
7
 * Publish your local business structured data.
8
 * Here you can tell Google about your business hours, different departments
9
 * within a business, reviews for your business, and more.
10
 *
11
 * ### required properties:
12
 *  - @id
13
 *    - [setURL()](#seturl)
14
 *  - PostalAddress
15
 *    - [setAdress()](#setadress)
16
 *  - name
17
 *    - [setInfo()](#setinfo)
18
 *  - telephone
19
 *
20
 * ### recommended properties:
21
 *  - url
22
 *  - geolocation
23
 *  - priceRange
24
 *  - openingHours
25
 *  - servesCuisine (recommended for 'FoodEstablishment' and subtypes of it)
26
 *  - logo
27
 *  - image
28
 *
29
 * ### additional poroperties
30
 *
31
 * #### aggregateRating (NOT supported so far)
32
 * The average rating of the local company, based on multiple ratings and
33
 * reviews. Review the guidelines for review snippets and the list of required
34
 * and recommended attributes for overall ratings.
35
 *
36
 * #### department(s)
37
 * (Type: nested LocalBusiness)
38
 * Nested element(s) for department(s). In this table you can define any
39
 * properties for a department.
40
 * Note: The id MUST differ from the id of the main business!
41
 * Additional guidelines: Enter the business name with the department name
42
 * in the following format:
43
 *        {store name} {department name}
44
 * Example:
45
 *        gMart and gMart Pharmacy.
46
 *
47
 * #### menu-card URL (NOT supported so far)
48
 * The fully qualified URL of the menu (for 'FoodEstablishment' and subtypes of it)
49
 *
50
 * #### review (NOT supported so far)
51
 * A review of the local company. Please refer to the guidelines for review
52
 * snippets and the list of required and recommended properties for reviews.
53
 *
54
 * @link https://developers.google.com/search/docs/data-types/local-business
55
 * @link https://schema.org/Organization
56
 * @link https://schema.org/LocalBusiness
57
 *
58
 * @package JsonLD
59
 * @author Stefanius <[email protected]>
60
 * @copyright MIT License - see the LICENSE file for details
61
 */
62
class JsonLDLocalBusiness extends JsonLD
63
{
64
    /**
65
     * Initializes a JsonLD object for local business.
66
     * Current host is set as URL and internal @id. In most cases this setting
67
     * should be correct. If different information is required, this setting
68
     * can be changed using the setURL() method.
69
     * > Valid values for 'strType' can be found in [Local Business Types](./Local-Business-Types)
70
     * @param string $strType
71
     * @param bool $bIsChild
72
     */
73
    public function __construct(string $strType = 'Organization', bool $bIsChild = false)
74
    {
75
        parent::__construct(self::LOCAL_BUSINESS, $strType, $bIsChild);
76
        $strID = $_SERVER['HTTP_HOST'] ?? 'UNKNOWN_HOST';
77
        if (!$bIsChild) {
78
            $this->aJsonLD["@id"] = $strID;
79
        }
80
        $this->aJsonLD["url"] = $strID;
81
    }
82
83
    /**
84
     * Set URL and id of the page.
85
     * Empty $strId will be set to $strURL. In the constructor the URL and Id is set
86
     * to the current host. Deviating values must most case only be set for departments
87
     * or if it is a special subpage of an Internet presence that is treated
88
     * differently from the main page.
89
     * @param string $strURL
90
     * @param string $strId
91
     */
92
    public function setURL(string $strURL, string $strId = '') : void
93
    {
94
        $strURL = $this->validURL($strURL);
95
        $strId = $this->validString($strId);
96
        if (strlen($strURL) > 0) {
97
            if (!$this->bIsChild || strlen($strId) > 0) {
98
                $this->aJsonLD["@id"] = strlen($strId) == 0 ? $strURL : $strId;
99
            }
100
            $this->aJsonLD["url"] = $strURL;
101
        }
102
    }
103
104
    /**
105
     * Set base informations about the organisation.
106
     * @param string $strName       mandatory property
107
     * @param string $strEMail      recommended property
108
     * @param string $strPhone      recommended property
109
     */
110
    public function setInfo(string $strName, string $strEMail = '', string $strPhone = '') : void
111
    {
112
        $strEMail = $this->validEMail($strEMail);
113
        $strName = $this->validString($strName);
114
        if (strlen($strName) > 0) {
115
            $this->aJsonLD["name"] = $this->validString($strName);
116
            if (strlen($strEMail) > 0) {
117
                $this->aJsonLD["email"] = $strEMail;
118
            }
119
            $strPhone = $this->validString($strPhone);
120
            if (strlen($strPhone) > 0) {
121
                $this->aJsonLD["telephone"] = $strPhone;
122
            }
123
        }
124
    }
125
126
    /**
127
     * Set postal adress of the business.
128
     * Here it makes sense to enter as many properties as possible. The more you
129
     * specify, the more informative the result will be for users.
130
     * @param string $strStreet
131
     * @param string $strPostcode
132
     * @param string $strCity
133
     * @param string $strRegion     (default: '')
134
     * @param string $strCountry    (default: '')
135
     */
136
    public function setAddress(string $strStreet, string $strPostcode, string $strCity, string $strRegion = '', string $strCountry = '') : void
137
    {
138
        $this->aJsonLD["address"] = $this->buildAddress($strStreet, $strPostcode, $strCity, $strRegion, $strCountry);
139
    }
140
141
    /**
142
     * Set the logo of the organization.
143
     * @param string $strLogoURL    URL to a valid image (PNG, GIF, JPG)
144
     */
145
    public function setLogo(string $strLogoURL) : void
146
    {
147
        $aLogo = $this->buildImageObject($strLogoURL);
148
        if ($aLogo != null) {
149
            $this->aJsonLD["logo"] = $aLogo;
150
        }
151
    }
152
153
    /**
154
     * The price range of the business, for example $$$.
155
     * Used by 'LocalBusinesses' and all subtypes of it. If you look closely, plain
156
     * text is ambiguous in this context... <br/>
157
     * Haven't really found any good explanation, how to use this property - anyway, google
158
     * mark it as recomended for 'LocalBusinesses' - just set it to some value ('$', ...).
159
     * @param string $strPriceRange
160
     */
161
    public function setPriceRange(string $strPriceRange) : void
162
    {
163
        $this->setProperty("priceRange", $strPriceRange);
164
    }
165
166
    /**
167
     * Recommended for 'FoodEstablishment' and subtypes of it.
168
     * @param string $strServesCuisine
169
     */
170
    public function setServesCuisine(string $strServesCuisine) : void
171
    {
172
        $this->setProperty("servesCuisine", $strServesCuisine);
173
    }
174
175
    /**
176
     * Short method to set opening hours.
177
     * Only set string like i.e. 'Mo.-Fr. 08:00-12:00 13:00-17:30'.
178
     * Don't use together with extended version addOpeningHours()!
179
     * @param string $strOpeningHours
180
     */
181
    public function setOpeningHours(string $strOpeningHours) : void
182
    {
183
        //  "openingHours": "Mo 09:00-12:00 We 12:00-17:00",
184
        $this->setProperty("openingHours", $strOpeningHours);
185
    }
186
187
    /**
188
     * Add valid language.
189
     * Multiple languages can be set for one business object.
190
     * @link https://www.w3.org/International/articles/language-tags/
191
     * @link https://www.w3.org/International/questions/qa-choosing-language-tags
192
     * @link https://tools.ietf.org/html/bcp47
193
     * @link https://schneegans.de/lv/
194
     * @link https://www.npmjs.com/package/bcp47-validate
195
     * @param string $strLang    language in IETF BCP 47 format
196
     */
197
    public function addLanguage(string $strLang) : void
198
    {
199
        if (!isset($this->aJsonLD["knowsLanguage"])) {
200
            $this->aJsonLD["knowsLanguage"] = array();
201
        }
202
        $this->aJsonLD["knowsLanguage"][] = $strLang;
203
    }
204
205
    /**
206
     * Add a contact to the Object.
207
     * The type must not contain any predefiend value, use it to describe the contact.
208
     * (i.e. 'Information', 'Hotline', 'Customer Service', 'Administration', ...)
209
     * @param string $strType
210
     * @param string $strEMail
211
     * @param string $strPhone
212
     * @return int  index of the added contact point
213
     */
214
    public function addContact(string $strType, string $strEMail = '', string $strPhone = '') : int
215
    {
216
        $iIndex = -1;
217
        $aCP = $this->buildContactPoint($strType, $strEMail, $strPhone);
218
        if ($aCP != null) {
219
            if (!isset($this->aJsonLD["contactPoint"])) {
220
                $this->aJsonLD["contactPoint"] = array();
221
            }
222
            $iIndex = count($this->aJsonLD["contactPoint"]);
223
            $this->aJsonLD["contactPoint"][] = $aCP;
224
        }
225
        return $iIndex;
226
    }
227
228
    /**
229
     * Add language to contact.
230
     * Multiple languages can be set for one contact.
231
     * @see JsonLDLocalBusiness::addLanguage()
232
     * @param int $iContact     index of the contact (returned by addContact())
233
     * @param string $strLang   language in IETF BCP 47 format
234
     */
235
    public function addContactLanguage(int $iContact, string $strLang) : void
236
    {
237
        if (isset($this->aJsonLD["contactPoint"]) && $iContact < count($this->aJsonLD["contactPoint"])) {
238
            if (!isset($this->aJsonLD["contactPoint"][$iContact]["availableLanguage"])) {
239
                $this->aJsonLD["contactPoint"][$iContact]["availableLanguage"] = array();
240
            }
241
            $this->aJsonLD["contactPoint"][$iContact]["availableLanguage"][] = $strLang;
242
        }
243
    }
244
245
    /**
246
     * Add URL of a reference Web page that unambiguously indicates the organizations identity.
247
     * E.g. the URL of the organizations social media page(s)
248
     * - facebook
249
     * - twitter
250
     * - instagramm
251
     * - wikipedia
252
     * - ...
253
     * @param string $strURL
254
     */
255
    public function addSameAs(string $strURL) : void
256
    {
257
        $strURL = $this->validURL($strURL);
258
        if (strlen($strURL) > 0) {
259
            if (!isset($this->aJsonLD["sameAs"])) {
260
                $this->aJsonLD["sameAs"] = array();
261
            }
262
            $this->aJsonLD["sameAs"][] = $strURL;
263
        }
264
    }
265
266
    /**
267
     * Extended method to set opening hours.
268
     * <b>!! Don't use together with short version `setOpeningHours()`! </b>
269
     * Multiple definitions may be set. <br/>
270
     * e.g.: <br/>
271
     * <pre><code>Mo     8:00...12:00, 13:00...17:30
272
     * Tu     8:00...12:00, 13:00...17:30
273
     * We     8:00...12:00
274
     * Th     8:00...12:00
275
     * Fr     8:00...12:00, 13:00...17:30
276
     *
277
     * addOpeningHours([1,1,1,1,1,0,0],  '8:00', '12:00');
278
     * addOpeningHours([1,1,0,0,1,0,0], '13:00', '17:30');
279
     * </code></pre>
280
     * <br/>
281
     * @todo openingHoursSpecification.validFrom / openingHoursSpecification.validThrough
282
     *
283
     * @param array<int> $aWeekdays      array containing 7 elements for each weekday (0-> Monday)
284
     * @param string $timeOpens     time opens
285
     * @param string $timeCloses    time closes
286
     * @return int  index of the added opening hours specification
287
     */
288
    public function addOpeningHours(array $aWeekdays, string $timeOpens, string $timeCloses) : int
289
    {
290
        $iIndex = -1;
291
        $timeOpens = $this->validTime($timeOpens);
292
        $timeCloses = $this->validTime($timeCloses);
293
        if (count($aWeekdays) == 7 && strlen($timeOpens) > 0 && strlen($timeCloses) > 0) {
294
            if (!isset($this->aJsonLD["location"])) {
295
                $this->aJsonLD["location"] = array("@type" => "Place");
296
            }
297
            if (!isset($this->aJsonLD["location"]["openingHoursSpecification"])) {
298
                $this->aJsonLD["location"]["openingHoursSpecification"] = array();
299
            }
300
            $iIndex = count($this->aJsonLD["location"]["openingHoursSpecification"]);
301
            $aOHS = array("@type" => "OpeningHoursSpecification");
302
            $aDayOfWeek = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunnday");
303
            for ($i = 0; $i < 7; $i++) {
304
                if ($aWeekdays[$i] != 1) {
305
                    unset($aDayOfWeek[$i]);
306
                }
307
            }
308
            $aDayOfWeek = array_values($aDayOfWeek);
309
            $aOHS["dayOfWeek"] = $aDayOfWeek;
310
            $aOHS["opens"] = $timeOpens;
311
            $aOHS["closes"] = $timeCloses;
312
            $this->aJsonLD["location"]["openingHoursSpecification"][] = $aOHS;
313
        }
314
        return $iIndex;
315
    }
316
317
    /**
318
     * Add department to the object.
319
     * Create a separate LocalBusiness object for each department you want to publish with
320
     * parameter `$bIsChild` of the constructor set tt `true`.
321
     * > <b>Important: </b><br/>
322
     * > !!! The id for each department MUST be set manually and MUST differ
323
     * from the id of the main (parent) object! <br/>
324
     * > <b>Additional guideline: </b><br/>
325
     * > Enter the business name with the department name in the following format: <br/>
326
     * > <i><b>{store name} {department name} </b> (i.e. 'MyCompany' and 'MyCompany Logistics'</i>.
327
     *
328
     * @param JsonLDLocalBusiness $oDepartment
329
     */
330
    public function addDepartment(JsonLDLocalBusiness $oDepartment) : void
331
    {
332
        $aDepartment = $oDepartment->getObject();
333
        if ($aDepartment != null) {
334
            if (!isset($this->aJsonLD["department"])) {
335
                $this->aJsonLD["department"] = array();
336
            }
337
            $this->aJsonLD["department"][] = $aDepartment;
338
        }
339
    }
340
}
341