1<?php
2/**
3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13namespace ComboStrap\Tag;
14
15
16use ComboStrap\ColorRgb;
17use ComboStrap\Dimension;
18use ComboStrap\ExceptionBadArgument;
19use ComboStrap\ExceptionCompile;
20use ComboStrap\ExecutionContext;
21use ComboStrap\LogUtility;
22use ComboStrap\MarkupPath;
23use ComboStrap\MarkupRenderUtility;
24use ComboStrap\PluginUtility;
25use ComboStrap\SiteConfig;
26use ComboStrap\Spacing;
27use ComboStrap\TagAttribute\Align;
28use ComboStrap\TagAttributes;
29
30/**
31 * Class AdsUtility
32 * @package ComboStrap
33 *
34 * TODO: Injection: Words Between Ads (https://wpadvancedads.com/manual/minimum-amount-of-words-between-ads/)
35 */
36class AdTag
37{
38
39    const CONF_ADS_MIN_LOCAL_LINE_DEFAULT = 2;
40    const CONF_ADS_MIN_LOCAL_LINE_KEY = '"AdsMinLocalLine"';
41    const CONF_ADS_LINE_BETWEEN_DEFAULT = 13;
42    const CONF_ADS_LINE_BETWEEN_KEY = 'AdsLineBetween';
43    const CONF_ADS_MIN_SECTION_NUMBER_DEFAULT = 2;
44    const CONF_ADS_MIN_SECTION_KEY = 'AdsMinSectionNumber';
45
46
47    const ADS_NAMESPACE = ':combostrap:ads:';
48
49    /**
50     * All in-article should start with this prefix
51     */
52    const PREFIX_IN_ARTICLE_ADS = "inarticle";
53
54    /**
55     * Do we show a placeholder when there is no ad page
56     * for a in-article
57     */
58    const CONF_IN_ARTICLE_PLACEHOLDER = 'AdsInArticleShowPlaceholder';
59    const CONF_IN_ARTICLE_PLACEHOLDER_DEFAULT = 0;
60    const MARKUP = "ad";
61    const NAME_ATTRIBUTE = "name";
62    const CONF_IN_ARTICLE_ENABLED = "combo-conf-007" ;
63    const CONF_IN_ARTICLE_ENABLED_DEFAULT = 0;
64
65    const CANONICAL = "ad";
66
67    public static function showAds($sectionLineCount, $currentLineCountSinceLastAd, $sectionNumber, $adsCounter, $isLastSection, ?MarkupPath $markupPath): bool
68    {
69        $isHiddenPage = false;
70        if ($markupPath !== null) {
71            try {
72                $isHiddenPage = isHiddenPage($markupPath->getWikiId());
73            } catch (ExceptionBadArgument $e) {
74                //
75            }
76        }
77        global $ACT;
78        if (
79            $ACT !== ExecutionContext::ADMIN_ACTION && // Not in the admin page
80            $isHiddenPage === false &&// No ads on hidden pages
81            (
82                (
83                    $sectionLineCount > self::CONF_ADS_MIN_LOCAL_LINE_DEFAULT && // Doesn't show any ad if the section does not contains this minimum number of line
84                    $currentLineCountSinceLastAd > self::CONF_ADS_LINE_BETWEEN_DEFAULT && // Every N line,
85                    $sectionNumber > self::CONF_ADS_MIN_SECTION_NUMBER_DEFAULT // Doesn't show any ad before
86                )
87                or
88                // Show always an ad after a number of section
89                (
90                    $adsCounter == 0 && // Still no ads
91                    $sectionNumber > self::CONF_ADS_MIN_SECTION_NUMBER_DEFAULT && // Above the minimum number of section
92                    $sectionLineCount > self::CONF_ADS_MIN_LOCAL_LINE_DEFAULT // Minimum line in the current section (to avoid a pub below a header)
93                )
94                or
95                // Sometimes the last section (reference) has not so much line and it avoids to show an ads at the end
96                // even if the number of line (space) was enough
97                (
98                    $isLastSection && // The last section
99                    $currentLineCountSinceLastAd > self::CONF_ADS_LINE_BETWEEN_DEFAULT  // Every N line,
100                )
101            )) {
102            return true;
103        } else {
104            return false;
105        }
106    }
107
108    public static function showPlaceHolder()
109    {
110        return SiteConfig::getConfValue(self::CONF_IN_ARTICLE_PLACEHOLDER, self::CONF_IN_ARTICLE_PLACEHOLDER_DEFAULT);
111    }
112
113    /**
114     * Return the full page location
115     * @param $name
116     * @return string
117     */
118    public static function getAdPage($name): string
119    {
120        return strtolower(self::ADS_NAMESPACE . $name);
121    }
122
123    /**
124     * Return the id of the div that wrap the ad
125     * @param $name - the name of the page ad
126     * @return string|string[]
127     */
128    public static function getTagId($name)
129    {
130        return str_replace(":", "-", substr(self::getAdPage($name), 1));
131    }
132
133    public static function render(TagAttributes $attributes): string
134    {
135
136        $name = $attributes->getValueAndRemoveIfPresent(self::NAME_ATTRIBUTE);
137        if ($name === null) {
138            return LogUtility::wrapInRedForHtml("Internal error: the name attribute is mandatory to render an ad");
139        }
140
141        $attributes->setId(AdTag::getTagId($name));
142
143        $adsPageId = AdTag::getAdPage($name);
144        if (!page_exists($adsPageId)) {
145
146            if (AdTag::showPlaceHolder()) {
147
148
149                $link = PluginUtility::getDocumentationHyperLink("automatic/in-article/ad#AdsInArticleShowPlaceholder", "In-article placeholder");
150                $htmlAttributes = $attributes
151                    ->setComponentAttributeValue(ColorRgb::COLOR, "dark")
152                    ->setComponentAttributeValue(Spacing::SPACING_ATTRIBUTE, "m-3 p-3")
153                    ->setComponentAttributeValue(Align::ALIGN_ATTRIBUTE, "center text-align")
154                    ->setComponentAttributeValue(Dimension::WIDTH_KEY, "600")
155                    ->setComponentAttributeValue("border-color", "dark")
156                    ->toHTMLAttributeString();
157                return <<<EOF
158<div $htmlAttributes>
159Ads Page Id ($adsPageId ) not found. <br>
160Showing the $link<br>
161</div>
162EOF;
163
164            }
165
166            return LogUtility::wrapInRedForHtml("The ad page (" . $adsPageId . ") does not exist");
167
168
169        }
170
171        try {
172            $content = MarkupRenderUtility::renderId2Xhtml($adsPageId);
173        } catch (ExceptionCompile $e) {
174            return LogUtility::wrapInRedForHtml("Error: " . $e->getMessage());
175        }
176
177        /**
178         * We wrap the ad with a div to locate it and id it
179         */
180        $htmlAttributesString = $attributes
181            ->toHTMLAttributeString();
182
183        return <<<EOF
184<div $htmlAttributesString>
185$content
186</div>
187EOF;
188
189    }
190}
191