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