Plugin Directory

source: ads-by-datafeedrcom/tags/1.1.3/inc/dfads.class.php

Last change on this file was 2003040, checked in by datafeedr.com, 6 years ago

Added 2 new filters.

File size: 11.2 KB
Line 
1<?php
2
3/**
4 * This class is responsible for querying the ads and
5 * formatting their output.
6 */
7class DFADS {
8
9        private $args;
10
11        // This is called via the dfads() function.  It puts everything in motion.
12        function get_ads( $args ) {
13               
14                $this->set_args( $args );
15                               
16                // Return JS output for avoiding caching issues.
17                // Return this before running query() to avoid:
18                // - The query being run twice.
19                // - Impressions being counted twice.
20                if ( $this->args['return_javascript'] == '1' ) {
21                        return $this->get_javascript();
22                }
23               
24                // Get ads.
25                $ads = $this->query();
26               
27                if ( empty($ads) ) { return false; }
28               
29                // Count impressions.
30                $this->update_impression_count( $ads );
31               
32                // Return user's own callback function.
33                if ( function_exists( $this->args['callback_function'] ) ) {
34                        return call_user_func_array($this->args['callback_function'], array( $ads, $this->args ));
35                }
36                               
37                // Return default output function.
38                return $this->output( $ads, $this->args );
39        }
40       
41        // Set up default arguements that can be modified in dfads().
42        function set_args( $args ) {
43       
44                // Undo anything that the text editor may have added.
45                $args = str_replace ( 
46                        array( "&amp;", "&lt;", "&gt;", "&quote;", "%2C" ), 
47                        array( "&",     "",     "",     "\"",      ","   ), 
48                        $args 
49                );
50       
51                // Now reformat
52                $args = htmlentities( $args );
53               
54                // Create array of values.
55                $args = explode("&amp;", $args);
56
57                $new_args = array();
58                foreach ($args as $arg) {
59                        $arr = explode( "=", $arg, 2 );
60                        $k = $arr[0];
61                        $v = $arr[1];
62                        // This section gets rid of the pesky "#038;" charcters WP changes "&" to.
63                        $k = str_replace( array( "#038;" ), array( "" ), $k );
64                        $new_args[$k] = $v;
65                }
66
67                $defaults = array (
68                        'groups'                        => '-1',
69                        'limit'                         => '-1',
70                        'orderby'                       => 'random',
71                        'order'                         => 'ASC',
72                        'container_id'          => '',
73                        'container_html'        => 'div',
74                        'container_class'       => '',
75                        'ad_html'                       => 'div',
76                        'ad_class'                      => '',
77                        'callback_function' => '',
78                        'return_javascript' => '',
79                );
80                               
81                $this->args = wp_parse_args( $new_args, $defaults );
82        }
83       
84        // Build the SQL query to get the ads.
85        function query() {
86                // http://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query
87                global $wpdb;
88                $tax_sql = $this->sql_get_taxonomy();
89                $tax_join = $tax_sql['JOIN'];
90                $tax_and = $tax_sql['AND'];
91                $limit = $this->sql_get_limit();
92                $orderby = $this->sql_get_orderby();
93                $order = $this->sql_get_order();
94                $sql = "
95                        SELECT
96                                p.*,
97                                imp_count.meta_value AS ad_imp_count,
98                                imp_limit.meta_value AS ad_imp_limit,
99                                start_date.meta_value AS ad_start_date,
100                                end_date.meta_value AS ad_end_date
101                        FROM $wpdb->posts p
102                        LEFT JOIN $wpdb->postmeta AS imp_limit
103                                ON p.ID = imp_limit.post_id     
104                                AND imp_limit.meta_key = '_dfads_impression_limit'
105                        LEFT JOIN $wpdb->postmeta AS imp_count
106                                ON p.ID = imp_count.post_id
107                                AND imp_count.meta_key = '".DFADS_METABOX_PREFIX."impression_count'
108                        LEFT JOIN $wpdb->postmeta AS start_date
109                                ON p.ID = start_date.post_id   
110                                AND start_date.meta_key = '_dfads_start_date'
111                        LEFT JOIN $wpdb->postmeta AS end_date
112                                ON p.ID = end_date.post_id
113                                AND end_date.meta_key = '_dfads_end_date'
114                        $tax_join
115                        WHERE p.post_status = 'publish'
116                        AND p.post_type = 'dfads'
117                        AND (
118                                CAST(imp_limit.meta_value AS UNSIGNED) = 0
119                                OR CAST(imp_count.meta_value AS UNSIGNED) < CAST(imp_limit.meta_value AS UNSIGNED)
120                                OR CAST(imp_count.meta_value AS UNSIGNED) IS NULL
121                        )
122                        AND (
123                                CAST(start_date.meta_value AS UNSIGNED) IS NULL
124                                OR ".time()." >= CAST(start_date.meta_value AS UNSIGNED)
125                        )
126                        AND (
127                                CAST(end_date.meta_value AS UNSIGNED) IS NULL
128                                OR ".time()." <= CAST(end_date.meta_value AS UNSIGNED)
129                        )
130                        $tax_and
131                        GROUP BY p.ID
132                        ORDER BY $orderby $order 
133                        LIMIT $limit
134                ";
135
136                return $wpdb->get_results( $sql, OBJECT );             
137        }
138       
139        // Build the taxonomy portion of the SQL statement.
140        function sql_get_taxonomy() {
141                global $wpdb;
142                $sql = array();
143                $sql['JOIN'] = '';
144                $sql['AND'] = '';
145               
146                if ( !$group_ids = $this->get_group_term_ids( $this->args['groups'] ) ) {
147                        return $sql;
148                }
149               
150                $ids = implode( ",", $group_ids );
151                $sql['JOIN'] = " LEFT JOIN $wpdb->term_relationships AS tr ON (p.ID = tr.object_id) LEFT JOIN $wpdb->term_taxonomy AS tax ON (tr.term_taxonomy_id = tax.term_taxonomy_id) ";
152                $sql['AND'] = " AND tax.taxonomy = 'dfads_group' AND tax.term_id IN($ids) ";
153                return $sql;
154        }
155
156        // Build the LIMIT portion of the SQL statement.
157        function sql_get_limit() {
158                return ($this->args['limit'] == '-1') ? 999 : intval($this->args['limit']);
159        }
160       
161        // Build the ORDER BY portion of the SQL statement.
162        function sql_get_orderby() {
163                $orderby_defaults = self::orderby_array();
164                return $orderby_defaults[$this->args['orderby']]['sql'];
165        }
166
167        // Build the ORDER portion of the SQL statement.       
168        function sql_get_order() {
169                return ($this->args['order'] == 'ASC') ? 'ASC' : 'DESC';
170        }
171       
172        // A set of possibly values for the ORDER BY part of the SQL query.
173        public static function orderby_array() {
174                return array(
175                        'ID' => array( 'name'=>'ID', 'sql'=>'p.ID' ),
176                        'post_title' => array( 'name'=>'Ad Title', 'sql'=>'p.post_title' ),
177                        'post_date' => array( 'name'=>'Date Created', 'sql'=>'p.post_date' ),
178                        'post_modified' => array( 'name'=>'Date Modified', 'sql'=>'p.post_modified' ),
179                        'menu_order' => array( 'name'=>'Menu Order', 'sql'=>'p.menu_order' ),
180                        'impression_count' => array( 'name'=>'Impression Count', 'sql'=>'CAST(imp_count.meta_value AS UNSIGNED)' ),
181                        'impression_limit' => array( 'name'=>'Impression Limit', 'sql'=>'CAST(imp_limit.meta_value AS UNSIGNED)' ),
182                        'start_date' => array( 'name'=>'Start Date', 'sql'=>'CAST(start_date.meta_value AS UNSIGNED)' ),
183                        'end_date' => array( 'name'=>'End Date', 'sql'=>'CAST(end_date.meta_value AS UNSIGNED)' ),
184                        'random' => array( 'name'=>'Random', 'sql'=>'RAND()' ),
185                );
186        }
187       
188        // This loops through all ads returned and updates their impression count (default: if user != admin).
189        function update_impression_count( $ads ) {
190               
191                // Don't count if admin AND admin impressions don't count.
192                if ( current_user_can('level_10') ) {
193                        $output = get_option( 'dfads-settings' );
194                        if ( !isset( $output['dfads_enable_count_for_admin'] ) || $output['dfads_enable_count_for_admin'] != '1' ) {
195                                return;
196                        }
197                }
198               
199                // Don't count if we've already set a block_id.
200                // This is to handle impresion counts for when 'return_javascript' equals 1
201                // because 'return_javascript' returns a <script> and <noscript> tag and
202                // we have to avoid the impression being counted twice.  So we store this
203                // ad groups unique "block_id" as a transient value to check subsequent calls
204                // for the same ad block.  If it's already set, we don't count again.
205                if ( isset( $this->args['_block_id'] ) ) {
206                        if ( get_transient( 'dfad_' . $this->args['_block_id'] ) ) {
207                                return;
208                        } else {
209                                set_transient( 'dfad_' . $this->args['_block_id'], true, 5 );
210                        }
211                }
212               
213                foreach ($ads as $ad) {
214                        update_post_meta($ad->ID, DFADS_METABOX_PREFIX.'impression_count', (intval($ad->ad_imp_count)+1));
215                }
216               
217        }
218       
219        // This formats and outputs the ads.  This is overridable if the user has defined $this->args['callback_function']
220        function output( $ads, $args ) {
221               
222                $ad_count = count( $ads );
223                $i = 1;
224                $html = '';
225               
226                // Determine if we should include tags for containers and ad wrappers.
227                // If 'none', then we remove the tag from output.
228                $container_html = ( $args['container_html'] == 'none' ) ? '' : $args['container_html'];
229                $ad_html = ( $args['ad_html'] == 'none' ) ? '' : $args['ad_html'];
230               
231                // If contain_html is not empty, get container's opening tag.
232                if ( $container_html != '') {
233                        $html .= $this->open_tag( $container_html, $args['container_class'], $args['container_id'] );
234                }
235               
236                // Loop through ads.
237                foreach ($ads as $ad) {
238               
239                        $first_last = ' ';
240                        if ( $i == 1 ) {
241                                $first_last = ' dfad_first ';
242                        } elseif ( $i == $ad_count ) {
243                                $first_last = ' dfad_last ';
244                        }
245                       
246                        // If ad_html is not empty, get the ads's opening tag.
247                        if ( $ad_html != '') {
248                                $html .= $this->open_tag( $ad_html, 'dfad dfad_pos_'.$i.$first_last.$args['ad_class'], $args['container_id'].'_ad_'.$ad->ID );
249                        }
250                       
251                        // Get ad content and append ad content to html block
252                        $html .= apply_filters( 'dfads_ad_post_content', $ad->post_content, $ad, $args );
253                       
254                        // If ad_html is not empty, get the ads's closing tag.
255                        if ( $ad_html != '') {
256                                $html .= $this->close_tag( $ad_html );
257                        }
258                       
259                        $i++;
260                }
261               
262                // If contain_html is not empty, get container's closing tag.
263                if ( $container_html != '') {
264                        $html .= $this->close_tag( $container_html );
265                }
266
267                return apply_filters( 'dfads_ads_html_block', $html, $ads, $args );
268        }
269       
270        function get_javascript() {
271               
272                $id = ( $this->args['container_id'] != '' ) ? $this->args['container_id'] : 'df'.$this->generate_random_string( 5 );
273               
274                // Set 'return_javascript' to '0' or else we end up with an infinite loop.
275                $args = $this->args;
276                $args['return_javascript'] = '0';
277                $args['_block_id'] = $id;
278                $args['container_html'] = 'none'; // Set to 'none' so we don't display the container HTML twice.
279               
280                return '
281                <'.$this->args['container_html'].' id="'.$id.'" class="dfads-javascript-load"></'.$this->args['container_html'].'>
282                <script>
283                (function($) {
284                        $("#'.$id .'").load("'.admin_url( 'admin-ajax.php?action=dfads_ajax_load_ads&'.http_build_query( $args ) ).'" );                       
285                })( jQuery );
286                </script>
287                <noscript>'.dfads( http_build_query( $args )  ).'</noscript>
288                ';
289               
290        }
291       
292        /**
293         * This gets the group IDs.
294         *
295         * $groups could be any of the following:
296         * - ''
297         * - 'groups='
298         * - 'groups=1'
299         * - 'groups=sidebar'
300         * - 'groups=1,2'
301         * - 'groups=sidebar,header'
302         *
303         * "-1" is equivalent to "All".
304         */
305        function get_group_term_ids( $groups=false ) {
306               
307                if (!$groups || $groups == '-1' || $groups == '') { return false; }
308       
309                $groups = explode(",", $groups);
310                $group_ids = array();
311       
312                foreach( $groups as $group ) {
313                       
314                        // Try to get term ID from id.
315                        if ($group_obj = get_term_by( 'id', $group, 'dfads_group' )) {
316                                $group_ids[] = intval($group_obj->term_id);
317                                continue;
318                        }
319               
320                        // Try to get term ID from slug.
321                        if ($group_obj = get_term_by( 'slug', $group, 'dfads_group' )) {
322                                $group_ids[] = intval($group_obj->term_id);
323                                continue;
324                        }
325               
326                        // Try to get term ID from name.
327                        if ($group_obj = get_term_by( 'name', $group, 'dfads_group' )) {
328                                $group_ids[] = intval($group_obj->term_id);
329                                continue;
330                        }
331                }
332       
333                if (!empty($group_ids)) {
334                        return $group_ids;
335                }
336       
337                return false;
338        }
339       
340        // Formats an opening HTML tag with CSS classes and IDs.
341        function open_tag( $tag='div', $class='', $id='' ) {
342                $tag = ($tag == '') ? 'div' : trim($tag);
343                $class = ($class != '') ? ' class="'.trim(esc_attr($class)).'"' : '';
344                $id = ($id != '') ? ' id="'.trim(esc_attr($id)).'"' : '';
345                return '<'.$tag.$class.$id.'>';
346        }
347
348        // Formats a closing HTML tag.
349        function close_tag( $tag='div' ) {
350                $tag = ($tag == '') ? 'div' : trim($tag);
351                return '</'.$tag.'>';
352        }
353       
354        // Helper function (http://stackoverflow.com/a/4356295)
355        function generate_random_string( $length=10 ) {
356                $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
357                $randomString = '';
358                for ( $i = 0; $i < $length; $i++ ) {
359                        $randomString .= $characters[rand(0, strlen($characters) - 1)];
360                }
361                return $randomString;
362        }
363}
Note: See TracBrowser for help on using the repository browser.