PluginProbe
Advanced Ads – Ad Manager & AdSense / 1.3.13
Advanced Ads – Ad Manager & AdSense v1.3.13
2.0.26 2.0.25 2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 All 348 releases
advanced-ads / classes / ad_group.php

ad_group.php in Advanced Ads – Ad Manager & AdSense 1.3.13, at classes/ad_group.php

363 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Advanced Ads
5 *
6 * @package Advads_Ad_Group
7 * @author Thomas Maier <thomas.maier@webgilde.com>
8 * @license GPL-2.0+
9 * @link http://webgilde.com
10 * @copyright 2014 Thomas Maier, webgilde GmbH
11 */
12
13 /**
14 * an ad group object
15 *
16 * @package Advads_Ad_Group
17 * @author Thomas Maier <thomas.maier@webgilde.com>
18 */
19 class Advads_Ad_Group {
20
21 /**
22 * default ad group weight
23 */
24 const MAX_AD_GROUP_WEIGHT = 10;
25
26 /**
27 * id of the taxonomy of this ad group
28 */
29 public $id = 0;
30
31 /**
32 * name of the taxonomy
33 */
34 protected $taxonomy = '';
35
36 /**
37 * post type of the ads
38 */
39 protected $post_type = '';
40
41 /**
42 * the current loaded ad
43 */
44 protected $current_ad = '';
45
46 /**
47 * the name of the term
48 */
49 public $name = '';
50
51 /**
52 * the slug of the term
53 */
54 public $slug = '';
55
56 /**
57 * the description of the term
58 */
59 public $description = '';
60
61 /**
62 * containing ad weights
63 */
64 private $ad_weights = 0;
65
66 /**
67 * array with post type objects (ads)
68 */
69 private $ads = array();
70
71 /**
72 * init ad group object
73 *
74 * @since 1.0.0
75 * @param int $id id of the ad group (= taxonomy id)
76 */
77 public function __construct($id) {
78 $id = absint($id);
79
80 if (empty($id))
81 return;
82
83 $this->id = $id;
84 $this->taxonomy = Advanced_Ads::AD_GROUP_TAXONOMY;
85 $this->post_type = Advanced_Ads::POST_TYPE_SLUG;
86
87 $this->load($id);
88 }
89
90 /**
91 * load an ad group object by id
92 *
93 * @since 1.0.0
94 */
95 private function load($id = 0) {
96 $_group = get_term($id, $this->taxonomy);
97 if ($_group == null)
98 return;
99
100 $this->name = $_group->name;
101 $this->slug = $_group->slug;
102 $this->description = $_group->description;
103 }
104
105 /**
106 * return random ad content for frontend output
107 *
108 * @since 1.0.0
109 * @return string ad content
110 */
111 public function output_random_ad() {
112 // see prepare_frontend_output for example for this filter
113 $ad = $this->get_random_ad();
114
115 if (!is_object($ad))
116 return '';
117
118 // add the group to the global output array
119 $advads = Advanced_Ads::get_instance();
120 $advads->current_ads[] = array('type' => 'group', 'id' => $this->id, 'title' => $this->name);
121
122 // makes sure the ad filters can also run here
123 $adcontent = $ad->output();
124
125 // filter again, in case a developer wants to filter group output individually
126 $output = apply_filters('advanced-ads-group-output', $adcontent, $this);
127
128 return $output;
129 }
130
131 /**
132 * get a random ad from this group
133 *
134 * @since 1.0.0
135 * @return
136 */
137 private function get_random_ad() {
138
139 // load all ads
140 $ads = $this->load_all_ads();
141
142 // return, if no ads given
143 if ($ads === array())
144 return;
145
146 // shuffle ads based on ad weight
147 $ads = $this->shuffle_ads($ads);
148
149 // check ads one by one for being able to be displayed on this spot
150 foreach ($ads as $_ad) {
151 // load the ad object
152 $ad = new Advads_Ad($_ad->ID);
153 if ($ad->can_display()) {
154 return $ad;
155 }
156 }
157
158 return '';
159 }
160
161 /**
162 * return all ads from this group
163 *
164 * @since 1.0.0
165 */
166 public function get_all_ads() {
167 if(count($this->ads) > 0)
168 return $this->ads;
169 else
170 return $this->load_all_ads();
171 }
172
173 /**
174 * load all public ads for this group
175 *
176 * @since 1.0.0
177 * @update 1.1.0 load only public ads
178 * @return arr $ads array with ad (post) objects
179 */
180 private function load_all_ads() {
181
182 $args = array(
183 'post_type' => $this->post_type,
184 'post_status' => 'publish',
185 'taxonomy' => $this->taxonomy,
186 'term' => $this->slug,
187 'orderby' => 'id'
188 );
189 $ads = new WP_Query($args);
190
191 if ($ads->have_posts()) {
192 return $this->ads = $this->add_post_ids($ads->posts);
193 } else {
194 return $this->ads = array();
195 }
196 }
197
198 /**
199 * use post ids as keys for ad array
200 *
201 * @since 1.0.0
202 * @param arr $ads array with post objects
203 * @return arr $ads array with post objects with post id as their key
204 * @todo check, if there isn’t a WP function for this already
205 */
206 private function add_post_ids(array $ads){
207
208 $ads_with_id = array();
209 foreach($ads as $_ad){
210 $ads_with_id[$_ad->ID] = $_ad;
211 }
212
213 return $ads_with_id;
214 }
215
216 /**
217 * shuffle ads based on ad weight
218 *
219 * @since 1.0.0
220 * @param arr $ads array with ad objects
221 * @return arr $shuffled_ads shuffled array with ad objects
222 */
223 private function shuffle_ads($ads = array()) {
224
225 // get saved ad weights
226 $weights = $this->get_ad_weights();
227
228 // if ads and weights don’t have the same keys, update weights array
229 if((count($weights) == 0 && count($ads) > 0) || count($weights) != count($ads) || array_diff_key($weights, $ads) != array()
230 || array_diff_key($ads, $weights) != array()) {
231 $this->update_ad_weights();
232 }
233
234 // get a random ad for every ad there is
235 $shuffled_ads = array();
236 // order array by ad weight; lowest first
237 asort($weights);
238 // while non-zero weights are set select random next
239 while (null !== $random_ad_id = $this->get_random_ad_by_weight($weights)) {
240 // remove chosen ad from weights array
241 unset($weights[$random_ad_id]);
242 // put random ad into shuffled array
243 if(!empty($ads[$random_ad_id]))
244 $shuffled_ads[] = $ads[$random_ad_id];
245 }
246
247 return $shuffled_ads;
248 }
249
250 /**
251 * get random ad by ad weight
252 *
253 * @since 1.0.0
254 * @param array $ad_weights e.g. array(A => 2, B => 3, C => 5)
255 * @source applied with fix for order http://stackoverflow.com/a/11872928/904614
256 */
257 private function get_random_ad_by_weight(array $ad_weights) {
258
259 // use maximum ad weight for ads without this
260 // ads might have a weight of zero (0); to avoid mt_rand fail assume that at least 1 is set.
261 $max = array_sum($ad_weights);
262 if ($max < 1) {
263 return ;
264 }
265
266 $rand = mt_rand(1, $max);
267
268 foreach ($ad_weights as $key => $value) {
269 $rand -= $value;
270 if ($rand <= 0) {
271 return $key;
272 }
273 }
274 }
275
276 /**
277 * get weights of ads in this group
278 *
279 * @since 1.0.0
280 */
281 public function get_ad_weights() {
282 // load and save ad weights if not yet set
283 if ($this->ad_weights == 0) {
284 $weights = get_option('advads-ad-weights', array());
285 if (isset($weights[$this->id])) {
286 return $this->ad_weights = $weights[$this->id];
287 }
288 } elseif(is_array($this->ad_weights)) { // return ad weigths if not empty
289 return $this->ad_weights;
290 }
291
292 // return empty array
293 return array();
294 }
295
296 /**
297 * save ad group weight (into global ad weight array)
298 *
299 * @since 1.0.0
300 * @param arr|str $weights array with ad weights (key: ad id; value: weight)
301 */
302 public function save_ad_weights($weights = '') {
303
304 // allow only arrays and empty string
305 if (!is_array($weights) && $weights = '')
306 return;
307
308 $global_weights = get_option('advads-ad-weights', array());
309
310 $global_weights[$this->id] = $this->sanitize_ad_weights($weights);
311
312 update_option('advads-ad-weights', $global_weights);
313
314 // refresh ad weights after update to avoid conflict
315 $this->ad_weights = $global_weights[$this->id];
316 }
317
318 /**
319 * update ad weight based on current ads for the group and ad weight
320 *
321 * @since 1.0.0
322 */
323 private function update_ad_weights(){
324 $ads = $this->get_all_ads();
325 $weights = $this->get_ad_weights();
326
327 $new_weights = array();
328 // use only ads assigned to the group
329 foreach($ads as $_ad){
330 if(isset($weights[$_ad->ID])){
331 $new_weights[$_ad->ID] = $weights[$_ad->ID];
332 } else {
333 // if no weight is given, use maximum default value
334 $new_weights[$_ad->ID] = self::MAX_AD_GROUP_WEIGHT;
335 }
336 }
337
338 $this->save_ad_weights($new_weights);
339 }
340
341 /**
342 * sanitize ad weights
343 *
344 * @since 1.0.0
345 * @param arr $weights ad weights array with (key: ad id; value: weight)
346 */
347 private function sanitize_ad_weights($weights = array()) {
348
349 if (!is_array($weights))
350 return '';
351
352 $sanitized_weights = array();
353 foreach ($weights as $_ad_id => $_weight) {
354 $_ad_id = absint($_ad_id);
355 $_weight = absint($_weight);
356 $sanitized_weights[$_ad_id] = $_weight;
357 }
358
359 return $sanitized_weights;
360 }
361
362 }
363