Guest User

Untitled

a guest
Mar 11th, 2018
1,125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 87.32 KB | None | 0 0
  1. <?php
  2.  
  3. function awpcp_esc_attr($text) {
  4. // WP adds slashes to all request variables
  5. $text = stripslashes($text);
  6. // AWPCP adds more slashes
  7. $text = stripslashes($text);
  8. $text = esc_attr($text);
  9. return $text;
  10. }
  11.  
  12. function awpcp_esc_textarea($text) {
  13. $text = stripslashes($text);
  14. $text = stripslashes($text);
  15. $text = esc_textarea($text);
  16. return $text;
  17. }
  18.  
  19. /**
  20. * @since 3.3
  21. */
  22. function awpcp_apply_function_deep( $function, $value ) {
  23. if ( is_array( $value ) ) {
  24. foreach ( $value as $key => $data ) {
  25. $value[ $key ] = awpcp_apply_function_deep( $function, $data );
  26. }
  27. } elseif ( is_object( $value ) ) {
  28. $vars = get_object_vars( $value );
  29. foreach ( $vars as $key => $data ) {
  30. $value->{$key} = awpcp_apply_function_deep( $function, $data );
  31. }
  32. } elseif ( is_string( $value ) ) {
  33. $value = call_user_func( $function, $value );
  34. }
  35.  
  36. return $value;
  37. }
  38.  
  39. /**
  40. * @since 3.3
  41. */
  42. function awpcp_strip_all_tags_deep( $string ) {
  43. return awpcp_apply_function_deep( 'wp_strip_all_tags', $string );
  44. }
  45.  
  46. /**
  47. * @since 3.0.2
  48. */
  49. function awpcp_strptime( $date, $format ) {
  50. if ( function_exists( 'strptime' ) ) {
  51. return strptime( $date, $format );
  52. } else {
  53. return awpcp_strptime_replacement( $date, $format );
  54. }
  55. }
  56.  
  57. /**
  58. * @since 3.0.2
  59. */
  60. function awpcp_strptime_replacement( $date, $format ) {
  61. $masks = array(
  62. '%d' => '(?P<d>[0-9]{2})',
  63. '%m' => '(?P<m>[0-9]{2})',
  64. '%y' => '(?P<y>[0-9]{2})',
  65. '%Y' => '(?P<Y>[0-9]{4})',
  66. '%H' => '(?P<H>[0-9]{2})',
  67. '%M' => '(?P<M>[0-9]{2})',
  68. '%S' => '(?P<S>[0-9]{2})',
  69. // usw..
  70. );
  71.  
  72. $regexp = "#" . strtr( preg_quote( $format ), $masks ) . "#";
  73. if ( ! preg_match( $regexp, $date, $out ) ) {
  74. return false;
  75. }
  76.  
  77. $unparsed = preg_replace( $regexp, '', $date );
  78.  
  79. if ( isset( $out['y'] ) && strlen( $out['y'] ) ) {
  80. $out['Y'] = ( $out['y'] > 69 ? 1900 : 2000 ) + $out['y'];
  81. }
  82.  
  83. $ret = array(
  84. 'tm_sec' => (int) awpcp_array_data( 'S', 0, $out),
  85. 'tm_min' => (int) awpcp_array_data( 'M', 0, $out),
  86. 'tm_hour' => (int) awpcp_array_data( 'H', 0, $out),
  87. 'tm_mday' => (int) awpcp_array_data( 'd', 0, $out),
  88. 'tm_mon' => awpcp_array_data( 'm', 0, $out) ? awpcp_array_data( 'm', 0, $out) - 1 : 0,
  89. 'tm_year' => awpcp_array_data( 'Y', 0, $out) > 1900 ? awpcp_array_data( 'Y', 0, $out) - 1900 : 0,
  90. 'unparsed' => $unparsed,
  91. );
  92.  
  93. return $ret;
  94. }
  95.  
  96. /**
  97. * @since 3.0
  98. */
  99. function awpcp_date_formats() {
  100. static $translations;
  101.  
  102. if ( ! is_array( $translations ) ) {
  103. $translations = array(
  104. 'd' => 'dd',
  105. 'j' => 'd',
  106. 's' => null,
  107. 'l' => 'DD',
  108. 'D' => 'D',
  109. 'm' => 'mm',
  110. 'n' => 'm',
  111. 'F' => 'MM',
  112. 'M' => 'M',
  113. 'Y' => 'yy',
  114. 'y' => 'y',
  115. 'c' => 'ISO_8601',
  116. 'r' => 'RFC_822',
  117. );
  118. }
  119.  
  120. return $translations;
  121. }
  122.  
  123.  
  124. /**
  125. * @since 3.0
  126. */
  127. function awpcp_time_formats() {
  128. static $translations;
  129.  
  130. if ( ! is_array( $translations ) ) {
  131. $translations = array(
  132. 'a' => 'p',
  133. 'A' => 'P',
  134. 'g' => 'h',
  135. 'h' => 'hh',
  136. 'G' => 'H',
  137. 'H' => 'HH',
  138. 'i' => 'mm',
  139. 's' => 'ss',
  140. 'T' => null,
  141. 'c' => null,
  142. 'r' => null
  143. );
  144. }
  145.  
  146. return $translations;
  147. }
  148.  
  149.  
  150. /**
  151. * Translates PHP date format strings to jQuery Datepicker format.
  152. * @since 3.0
  153. */
  154. function awpcp_datepicker_format($format) {
  155. return _awpcp_replace_format($format, awpcp_date_formats());
  156. }
  157.  
  158. /**
  159. * Translates PHP time format strings to jQuery TimePicker format.
  160. * @since 3.0
  161. */
  162. function awpcp_timepicker_format($format) {
  163. return _awpcp_replace_format($format, awpcp_time_formats());
  164. }
  165.  
  166.  
  167. /**
  168. * @since 3.0
  169. */
  170. function _awpcp_replace_format($format, $translations) {
  171. $pattern = join( '|', array_map( 'preg_quote', array_keys( $translations ) ) );
  172.  
  173. preg_match_all( "/$pattern/s", $format, $matches );
  174.  
  175. $processed = array();
  176. foreach ( $matches[0] as $match ) {
  177. if ( ! isset( $processed[ $match ] ) ) {
  178. $format = str_replace( $match, $translations[ $match ], $format );
  179. $processed[ $match ] = true;
  180. }
  181. }
  182.  
  183. return $format;
  184. }
  185.  
  186.  
  187. /**
  188. * @since 3.0
  189. */
  190. function awpcp_get_date_format() {
  191. return get_awpcp_option('date-format');
  192. }
  193.  
  194.  
  195. /**
  196. * @since 3.0
  197. */
  198. function awpcp_get_time_format() {
  199. return get_awpcp_option('time-format');
  200. }
  201.  
  202.  
  203. /**
  204. * @since 3.0
  205. */
  206. function awpcp_get_datetime_format() {
  207. $format = get_awpcp_option('date-time-format');
  208. $format = str_replace('<date>', '******', $format);
  209. $format = str_replace('<time>', '*^*^*^', $format);
  210. $format = preg_replace('/(\w)/', '\\\\$1', $format);
  211. $format = str_replace('******', awpcp_get_date_format(), $format);
  212. $format = str_replace('*^*^*^', awpcp_get_time_format(), $format);
  213. return $format;
  214. }
  215.  
  216. /**
  217. * Returns the given date as MySQL date string, Unix timestamp or
  218. * using a custom format.
  219. *
  220. * @since 3.0.2
  221. * @param $format 'mysql', 'timestamp', 'awpcp', 'awpcp-date', 'awpcp-time'
  222. * or first arguemnt for date() function.
  223. */
  224. function awpcp_datetime( $format='mysql', $date=null ) {
  225. if ( is_null( $date ) || strlen( $date ) === 0 ) {
  226. $timestamp = current_time( 'timestamp' );
  227. } else if ( is_string( $date ) ) {
  228. $timestamp = strtotime( $date );
  229. } else {
  230. $timestamp = $date;
  231. }
  232.  
  233. switch ( $format ) {
  234. case 'mysql':
  235. return date( 'Y-m-d H:i:s', $timestamp );
  236. case 'timestamp':
  237. return $timestamp;
  238. case 'time-elapsed':
  239. return sprintf( __( '%s ago' ), human_time_diff( strtotime( $date ) ) );
  240. case 'awpcp':
  241. return date_i18n( awpcp_get_datetime_format(), $timestamp ) ;
  242. case 'awpcp-date':
  243. return date_i18n( awpcp_get_date_format(), $timestamp );
  244. case 'awpcp-time':
  245. return date_i18n( awpcp_get_time_format(), $timestamp );
  246. default:
  247. return date_i18n( $format, $timestamp );
  248. }
  249. }
  250.  
  251. function awpcp_set_datetime_date( $datetime, $date ) {
  252. $base_timestamp = strtotime( $datetime );
  253. $base_year_month_day_timestamp = strtotime( date( 'Y-m-d', strtotime( $datetime ) ) );
  254. $time_of_the_day_in_seconds = $base_timestamp - $base_year_month_day_timestamp;
  255.  
  256. $target_year_month_day_timestamp = strtotime( date( 'Y-m-d', strtotime( $date ) ) );
  257.  
  258. $new_datetime_timestamp = $target_year_month_day_timestamp + $time_of_the_day_in_seconds;
  259.  
  260. return awpcp_datetime( 'mysql', $new_datetime_timestamp );
  261. }
  262.  
  263. function awpcp_extend_date_to_end_of_the_day( $datetime ) {
  264. $next_day = strtotime( '+ 1 days', $datetime );
  265. $zero_hours_next_day = strtotime( date( 'Y-m-d', $next_day ) );
  266. $end_of_the_day = $zero_hours_next_day - 1;
  267.  
  268. return $end_of_the_day;
  269. }
  270.  
  271. function awpcp_is_mysql_date( $date ) {
  272. $regexp = '/^\d{4}-\d{1,2}-\d{1,2}(\s\d{1,2}:\d{1,2}(:\d{1,2})?)?$/';
  273. return preg_match( $regexp, $date ) === 1;
  274. }
  275.  
  276.  
  277. /**
  278. * Returns a WP capability required to be considered an AWPCP admin.
  279. *
  280. * http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table
  281. *
  282. * @since 2.0.7
  283. */
  284. function awpcp_admin_capability() {
  285. return 'manage_classifieds';
  286. }
  287.  
  288. /**
  289. * @since 3.3.2
  290. */
  291. function awpcp_admin_roles_names() {
  292. return awpcp_roles_and_capabilities()->get_administrator_roles_names();
  293. }
  294.  
  295. /**
  296. * Check if current user is an Administrator according to
  297. * AWPCP settings.
  298. */
  299. function awpcp_current_user_is_admin() {
  300. return awpcp_roles_and_capabilities()->current_user_is_administrator();
  301. }
  302.  
  303. /**
  304. * @since 3.4
  305. */
  306. function awpcp_current_user_is_moderator() {
  307. return awpcp_roles_and_capabilities()->current_user_is_moderator();
  308. }
  309.  
  310.  
  311. function awpcp_user_is_admin($id) {
  312. return awpcp_roles_and_capabilities()->user_is_administrator( $id );
  313. }
  314.  
  315.  
  316. function awpcp_get_grid_item_css_class($classes, $pos, $columns, $rows) {
  317. if ($pos < $columns)
  318. $classes[] = 'first-row';
  319. if ($pos >= (($rows - 1) * $columns))
  320. $classes[] = 'last-row';
  321. if ($pos == 0 || $pos % $columns == 0)
  322. $classes[] = 'first-column';
  323. if (($pos + 1) % $columns == 0)
  324. $classes[] = 'last-column';
  325. return $classes;
  326. }
  327.  
  328. /**
  329. * @since 3.0
  330. * @param array $params
  331. * @param string $url
  332. * @return String HTML
  333. */
  334. function awpcp_pagination($config, $url) {
  335.  
  336. $blacklist = array(
  337. 'offset',
  338. 'results',
  339. 'PHPSESSID',
  340. 'aeaction',
  341. 'cat_ID',
  342. 'action',
  343. 'aeaction',
  344. 'category_name',
  345. 'category_parent_id',
  346. 'createeditadcategory',
  347. 'deletemultiplecategories',
  348. 'movedeleteads',
  349. 'moveadstocategory',
  350. 'category_to_delete',
  351. 'tpname',
  352. 'category_icon',
  353. 'sortby',
  354. 'adid',
  355. 'picid',
  356. 'adkey',
  357. 'editemail',
  358. 'awpcp_ads_to_action',
  359. 'post_type');
  360.  
  361. $params = array_merge($_GET, $_POST);
  362. foreach ($blacklist as $param) {
  363. unset($params[$param]);
  364. }
  365.  
  366. extract(shortcode_atts(array('offset' => 0, 'results' => 10, 'total' => 10), $config));
  367.  
  368. $items = array();
  369. $radius = 5;
  370.  
  371. if ( $results > 0 ) {
  372. $pages = ceil($total / $results);
  373. $page = floor($offset / $results) + 1;
  374. } else {
  375. $pages = 1;
  376. $page = 1;
  377. }
  378.  
  379. if ( ( $page - $radius ) > 2 ) {
  380. $items[] = awpcp_render_pagination_item( '&laquo;&laquo;', 1, $results, $params, $url );
  381. }
  382.  
  383. if ( $page > 1 ) {
  384. $items[] = awpcp_render_pagination_item( '&laquo;', $page - 1, $results, $params, $url );
  385. }
  386.  
  387. for ($i=1; $i <= $pages; $i++) {
  388. if ( $page == $i ) {
  389. $items[] = sprintf('%d', $i);
  390. } else if ( $i < ( $page - $radius ) ) {
  391. // pass
  392. } else if ( $i > ( $page + $radius ) ) {
  393. // pass
  394. } else {
  395. $items[] = awpcp_render_pagination_item( $i, $i, $results, $params, $url );
  396. }
  397. }
  398.  
  399. if ( $page < ( $pages - 1 ) ) {
  400. $items[] = awpcp_render_pagination_item( '&raquo;', $page + 1, $results, $params, $url );
  401. }
  402.  
  403. if ( ( $page + $radius ) < ( $pages - 1 ) ) {
  404. $items[] = awpcp_render_pagination_item( '&raquo;&raquo;', $pages, $results, $params, $url );
  405. }
  406.  
  407. $pagination = implode( '', $items );
  408. $options = awpcp_pagination_options( $results );
  409.  
  410. ob_start();
  411. include(AWPCP_DIR . '/frontend/templates/listings-pagination.tpl.php');
  412. $html = ob_get_contents();
  413. ob_end_clean();
  414.  
  415. return $html;
  416. }
  417.  
  418. function awpcp_render_pagination_item( $label, $page, $results_per_page, $params, $url ) {
  419. $params = array_merge(
  420. $params,
  421. array(
  422. 'offset' => ( $page - 1 ) * $results_per_page,
  423. 'results' => $results_per_page,
  424. )
  425. );
  426.  
  427. $url = add_query_arg( urlencode_deep( $params ), $url );
  428.  
  429. return sprintf( '<a href="%s">%s</a>', esc_url( $url ), $label );
  430. }
  431.  
  432. /**
  433. * @since 3.2.1
  434. */
  435. function awpcp_pagination_options( $selected=10 ) {
  436. $options = get_awpcp_option( 'pagination-options' );
  437. return awpcp_build_pagination_options( $options, $selected );
  438. }
  439.  
  440. /**
  441. * @since 3.3.2
  442. */
  443. function awpcp_build_pagination_options( $options, $selected ) {
  444. array_unshift( $options, 0 );
  445.  
  446. for ( $i = count( $options ) - 1; $i >= 0; $i-- ) {
  447. if ( $options[ $i ] < $selected ) {
  448. array_splice( $options, $i + 1, 0, $selected );
  449. break;
  450. }
  451. }
  452.  
  453. $options_without_zero = array_filter( $options, 'intval' );
  454.  
  455. return array_combine( $options_without_zero , $options_without_zero );
  456. }
  457.  
  458. /**
  459. * @since 3.3.2
  460. */
  461. function awpcp_default_pagination_options( $selected = 10 ) {
  462. $default_options = awpcp()->settings->get_option_default_value( 'pagination-options' );
  463. return awpcp_build_pagination_options( $default_options, $selected );
  464. }
  465.  
  466. function awpcp_get_categories() {
  467. global $wpdb;
  468.  
  469. $sql = 'SELECT * FROM ' . AWPCP_TABLE_CATEGORIES;
  470. $results = $wpdb->get_results($sql);
  471.  
  472. return $results;
  473. }
  474.  
  475. function awpcp_get_categories_ids() {
  476. static $categories;
  477.  
  478. if (!is_array($categories)) {
  479. $categories = awpcp_get_properties( awpcp_get_categories(), 'category_id' );
  480. }
  481.  
  482. return $categories;
  483. }
  484.  
  485. /**
  486. * @since 3.0
  487. */
  488. function awpcp_get_comma_separated_categories_list($categories=array(), $threshold=5) {
  489. $names = awpcp_get_properties( $categories, 'name' );
  490. return awpcp_get_comma_separated_list( $names, $threshold, __( 'None', 'another-wordpress-classifieds-plugin' ) );
  491. }
  492.  
  493. /**
  494. * @since 3.0
  495. */
  496. function awpcp_get_comma_separated_list($items=array(), $threshold=5, $none='') {
  497. $items = array_filter( $items, 'strlen' );
  498. $count = count( $items );
  499.  
  500. if ( $count > $threshold ) {
  501. $message = _x( '%s and %d more.', 'comma separated list of things', 'another-wordpress-classifieds-plugin' );
  502. $items = array_splice( $items, 0, $threshold - 1 );
  503. return sprintf( $message, join( ', ', $items ), $count - $threshold + 1 );
  504. } else if ( $count > 0 ) {
  505. return sprintf( '%s.', join( ', ', $items ) );
  506. } else {
  507. return $none;
  508. }
  509. }
  510.  
  511. /**
  512. * Returns an array of Region fields. Only those enabled
  513. * in the settings will be returned.
  514. *
  515. * @param $translations array Allow developers to change the name
  516. * attribute of the form field associated
  517. * to this Region Field.
  518. * @since 3.0.2
  519. */
  520. function awpcp_region_fields( $context='details', $enabled_fields = null ) {
  521. $enabled_fields = is_null( $enabled_fields ) ? awpcp_get_enabled_region_fields() : $enabled_fields;
  522.  
  523. $fields = apply_filters( 'awpcp-region-fields', false, $context, $enabled_fields );
  524.  
  525. if ( false === $fields ) {
  526. $fields = awpcp_default_region_fields( $context, $enabled_fields );
  527. }
  528.  
  529. return $fields;
  530. }
  531.  
  532. /**
  533. * @since 3.3.1
  534. */
  535. function awpcp_get_enabled_region_fields() {
  536. return array(
  537. 'country' => get_awpcp_option( 'displaycountryfield' ),
  538. 'state' => get_awpcp_option( 'displaystatefield' ),
  539. 'city' => get_awpcp_option( 'displaycityfield' ),
  540. 'county' => get_awpcp_option( 'displaycountyvillagefield' ),
  541. );
  542. }
  543.  
  544. /**
  545. * @since 3.0.2
  546. */
  547. function awpcp_default_region_fields( $context='details', $enabled_fields = null ) {
  548. $enabled_fields = is_null( $enabled_fields ) ? awpcp_get_enabled_region_fields() : $enabled_fields;
  549. $show_city_field_before_county_field = get_awpcp_option( 'show-city-field-before-county-field' );
  550.  
  551. $always_shown = in_array( $context, array( 'details', 'search', 'user-profile' ) );
  552. $can_be_required = $context !== 'search';
  553. $_fields = array();
  554.  
  555. if ( $enabled_fields['country'] ) {
  556. $required = $can_be_required && ( (bool) get_awpcp_option( 'displaycountryfieldreqop' ) );
  557. $_fields['country'] = array(
  558. 'type' => 'country',
  559. 'label' => __('Country', 'another-wordpress-classifieds-plugin') . ( $required ? '*' : '' ),
  560. 'help' => __('separate countries by commas', 'another-wordpress-classifieds-plugin'),
  561. 'required' => $required,
  562. 'alwaysShown' => $always_shown,
  563. );
  564. }
  565. if ( $enabled_fields['state'] ) {
  566. $required = $can_be_required && ( (bool) get_awpcp_option( 'displaystatefieldreqop' ) );
  567. $_fields['state'] = array(
  568. 'type' => 'state',
  569. 'label' => __('State/Province', 'another-wordpress-classifieds-plugin') . ( $required ? '*' : '' ),
  570. 'help' => __('separate states by commas', 'another-wordpress-classifieds-plugin'),
  571. 'required' => $required,
  572. 'alwaysShown' => $always_shown,
  573. );
  574. }
  575. if ( $enabled_fields['city'] ) {
  576. $required = $can_be_required && ( (bool) get_awpcp_option( 'displaycityfieldreqop' ) );
  577. $_fields['city'] = array(
  578. 'type' => 'city',
  579. 'label' => __('City', 'another-wordpress-classifieds-plugin') . ( $required ? '*' : '' ),
  580. 'help' => __('separate cities by commas', 'another-wordpress-classifieds-plugin'),
  581. 'required' => $required,
  582. 'alwaysShown' => $always_shown,
  583. );
  584. }
  585. if ( $enabled_fields['county'] ) {
  586. $required = $can_be_required && ( (bool) get_awpcp_option( 'displaycountyvillagefieldreqop' ) );
  587. $_fields['county'] = array(
  588. 'type' => 'county',
  589. 'label' => __('County/Village/Other', 'another-wordpress-classifieds-plugin') . ( $required ? '*' : '' ),
  590. 'help' => __('separate counties by commas', 'another-wordpress-classifieds-plugin'),
  591. 'required' => $required,
  592. 'alwaysShown' => $always_shown,
  593. );
  594. }
  595.  
  596. if ( ! $show_city_field_before_county_field ) {
  597. $fields = array();
  598. foreach( array( 'country', 'state', 'county', 'city' ) as $field ) {
  599. if ( isset( $_fields[ $field ] ) ) {
  600. $fields[ $field ] = $_fields[ $field ];
  601. }
  602. }
  603. } else {
  604. $fields = $_fields;
  605. }
  606.  
  607. return $fields;
  608. }
  609.  
  610. function awpcp_country_list_options($value=false, $use_names=true) {
  611. $countries = array(
  612. 'US' => 'United States',
  613. 'AL' => 'Albania',
  614. 'DZ' => 'Algeria',
  615. 'AD' => 'Andorra',
  616. 'AO' => 'Angola',
  617. 'AI' => 'Anguilla',
  618. 'AG' => 'Antigua and Barbuda',
  619. 'AR' => 'Argentina',
  620. 'AM' => 'Armenia',
  621. 'AW' => 'Aruba',
  622. 'AU' => 'Australia',
  623. 'AT' => 'Austria',
  624. 'AZ' => 'Azerbaijan Republic',
  625. 'BS' => 'Bahamas',
  626. 'BH' => 'Bahrain',
  627. 'BB' => 'Barbados',
  628. 'BE' => 'Belgium',
  629. 'BZ' => 'Belize',
  630. 'BJ' => 'Benin',
  631. 'BM' => 'Bermuda',
  632. 'BT' => 'Bhutan',
  633. 'BO' => 'Bolivia',
  634. 'BA' => 'Bosnia and Herzegovina',
  635. 'BW' => 'Botswana',
  636. 'BR' => 'Brazil',
  637. 'BN' => 'Brunei',
  638. 'BG' => 'Bulgaria',
  639. 'BF' => 'Burkina Faso',
  640. 'BI' => 'Burundi',
  641. 'KH' => 'Cambodia',
  642. 'CA' => 'Canada',
  643. 'CV' => 'Cape Verde',
  644. 'KY' => 'Cayman Islands',
  645. 'TD' => 'Chad',
  646. 'CL' => 'Chile',
  647. 'C2' => 'China',
  648. 'CO' => 'Colombia',
  649. 'KM' => 'Comoros',
  650. 'CK' => 'Cook Islands',
  651. 'CR' => 'Costa Rica',
  652. 'HR' => 'Croatia',
  653. 'CY' => 'Cyprus',
  654. 'CZ' => 'Czech Republic',
  655. 'CD' => 'Democratic Republic of the Congo',
  656. 'DK' => 'Denmark',
  657. 'DJ' => 'Djibouti',
  658. 'DM' => 'Dominica',
  659. 'DO' => 'Dominican Republic',
  660. 'EC' => 'Ecuador',
  661. 'SV' => 'El Salvador',
  662. 'ER' => 'Eritrea',
  663. 'EE' => 'Estonia',
  664. 'ET' => 'Ethiopia',
  665. 'FK' => 'Falkland Islands',
  666. 'FO' => 'Faroe Islands',
  667. 'FJ' => 'Fiji',
  668. 'FI' => 'Finland',
  669. 'FR' => 'France',
  670. 'GF' => 'French Guiana',
  671. 'PF' => 'French Polynesia',
  672. 'GA' => 'Gabon Republic',
  673. 'GM' => 'Gambia',
  674. 'DE' => 'Germany',
  675. 'GI' => 'Gibraltar',
  676. 'GR' => 'Greece',
  677. 'GL' => 'Greenland',
  678. 'GD' => 'Grenada',
  679. 'GP' => 'Guadeloupe',
  680. 'GT' => 'Guatemala',
  681. 'GN' => 'Guinea',
  682. 'GW' => 'Guinea Bissau',
  683. 'GY' => 'Guyana',
  684. 'HN' => 'Honduras',
  685. 'HK' => 'Hong Kong',
  686. 'HU' => 'Hungary',
  687. 'IS' => 'Iceland',
  688. 'IN' => 'India',
  689. 'ID' => 'Indonesia',
  690. 'IE' => 'Ireland',
  691. 'IL' => 'Israel',
  692. 'IT' => 'Italy',
  693. 'JM' => 'Jamaica',
  694. 'JP' => 'Japan',
  695. 'JO' => 'Jordan',
  696. 'KZ' => 'Kazakhstan',
  697. 'KE' => 'Kenya',
  698. 'KI' => 'Kiribati',
  699. 'KW' => 'Kuwait',
  700. 'KG' => 'Kyrgyzstan',
  701. 'LA' => 'Laos',
  702. 'LV' => 'Latvia',
  703. 'LS' => 'Lesotho',
  704. 'LI' => 'Liechtenstein',
  705. 'LT' => 'Lithuania',
  706. 'LU' => 'Luxembourg',
  707. 'MG' => 'Madagascar',
  708. 'MW' => 'Malawi',
  709. 'MY' => 'Malaysia',
  710. 'MV' => 'Maldives',
  711. 'ML' => 'Mali',
  712. 'MT' => 'Malta',
  713. 'MH' => 'Marshall Islands',
  714. 'MQ' => 'Martinique',
  715. 'MR' => 'Mauritania',
  716. 'MU' => 'Mauritius',
  717. 'YT' => 'Mayotte',
  718. 'MX' => 'Mexico',
  719. 'FM' => 'Micronesia',
  720. 'MN' => 'Mongolia',
  721. 'MS' => 'Montserrat',
  722. 'MA' => 'Morocco',
  723. 'MZ' => 'Mozambique',
  724. 'NA' => 'Namibia',
  725. 'NR' => 'Nauru',
  726. 'NP' => 'Nepal',
  727. 'NL' => 'Netherlands',
  728. 'AN' => 'Netherlands Antilles',
  729. 'NC' => 'New Caledonia',
  730. 'NZ' => 'New Zealand',
  731. 'NI' => 'Nicaragua',
  732. 'NE' => 'Niger',
  733. 'NU' => 'Niue',
  734. 'NF' => 'Norfolk Island',
  735. 'NO' => 'Norway',
  736. 'OM' => 'Oman',
  737. 'PW' => 'Palau',
  738. 'PA' => 'Panama',
  739. 'PG' => 'Papua New Guinea',
  740. 'PE' => 'Peru',
  741. 'PH' => 'Philippines',
  742. 'PN' => 'Pitcairn Islands',
  743. 'PL' => 'Poland',
  744. 'PT' => 'Portugal',
  745. 'QA' => 'Qatar',
  746. 'CG' => 'Republic of the Congo',
  747. 'RE' => 'Reunion',
  748. 'RO' => 'Romania',
  749. 'RU' => 'Russia',
  750. 'RW' => 'Rwanda',
  751. 'KN' => 'Saint Kitts and Nevis Anguilla',
  752. 'PM' => 'Saint Pierre and Miquelon',
  753. 'VC' => 'Saint Vincent and Grenadines',
  754. 'WS' => 'Samoa',
  755. 'SM' => 'San Marino',
  756. 'ST' => 'São Tomé and Príncipe',
  757. 'SA' => 'Saudi Arabia',
  758. 'SN' => 'Senegal',
  759. 'SC' => 'Seychelles',
  760. 'SL' => 'Sierra Leone',
  761. 'SG' => 'Singapore',
  762. 'SK' => 'Slovakia',
  763. 'SI' => 'Slovenia',
  764. 'SB' => 'Solomon Islands',
  765. 'SO' => 'Somalia',
  766. 'ZA' => 'South Africa',
  767. 'KR' => 'South Korea',
  768. 'ES' => 'Spain',
  769. 'LK' => 'Sri Lanka',
  770. 'SH' => 'St. Helena',
  771. 'LC' => 'St. Lucia',
  772. 'SR' => 'Suriname',
  773. 'SJ' => 'Svalbard and Jan Mayen Islands',
  774. 'SZ' => 'Swaziland',
  775. 'SE' => 'Sweden',
  776. 'CH' => 'Switzerland',
  777. 'TW' => 'Taiwan',
  778. 'TJ' => 'Tajikistan',
  779. 'TZ' => 'Tanzania',
  780. 'TH' => 'Thailand',
  781. 'TG' => 'Togo',
  782. 'TO' => 'Tonga',
  783. 'TT' => 'Trinidad and Tobago',
  784. 'TN' => 'Tunisia',
  785. 'TR' => 'Turkey',
  786. 'TM' => 'Turkmenistan',
  787. 'TC' => 'Turks and Caicos Islands',
  788. 'TV' => 'Tuvalu',
  789. 'UG' => 'Uganda',
  790. 'UA' => 'Ukraine',
  791. 'AE' => 'United Arab Emirates',
  792. 'GB' => 'United Kingdom',
  793. 'UY' => 'Uruguay',
  794. 'VU' => 'Vanuatu',
  795. 'VA' => 'Vatican City State',
  796. 'VE' => 'Venezuela',
  797. 'VN' => 'Vietnam',
  798. 'VG' => 'Virgin Islands (British)',
  799. 'WF' => 'Wallis and Futuna Islands',
  800. 'YE' => 'Yemen',
  801. 'ZM' => 'Zambia',
  802. );
  803.  
  804. $options[] ='<option value="">' . __('-- Choose a Country --', 'another-wordpress-classifieds-plugin') . '</option>';
  805.  
  806. foreach ($countries as $code => $name) {
  807. if ($use_names) {
  808. $selected = $value == $name ? ' selected="selected"' : '';
  809. $options[] = sprintf('<option value="%s"%s>%s</option>', $name, $selected, $name);
  810. } else {
  811. $selected = $value == $code ? ' selected="selected"' : '';
  812. $options[] = sprintf('<option value="%s"%s>%s</option>', $code, $selected, $name);
  813. }
  814. }
  815.  
  816. return join('', $options);
  817. }
  818.  
  819.  
  820. /**
  821. * AWPCP misc functions
  822. *
  823. * TODO: merge content from functions_awpcp.php,
  824. * fileop.class.php, dcfunctions.php, upload_awpcp.php
  825. * as needed.
  826. */
  827.  
  828. /**
  829. * @deprecated 3.0.2 use $media->get_url()
  830. */
  831. function awpcp_get_image_url($image, $suffix='') {
  832. _deprecated_function( __FUNCTION__, '3.0.2', 'AWPCP_Media::get_url()' );
  833.  
  834. static $uploads = array();
  835.  
  836. if ( empty( $uploads ) ) {
  837. $uploads = awpcp_setup_uploads_dir();
  838. $uploads = array_shift( $uploads );
  839. }
  840.  
  841. $images = trailingslashit(AWPCPUPLOADURL);
  842. $thumbnails = trailingslashit(AWPCPTHUMBSUPLOADURL);
  843.  
  844. if (is_object($image))
  845. $basename = $image->image_name;
  846. if (is_string($image))
  847. $basename = $image;
  848.  
  849. $original = $images . $basename;
  850. $thumbnail = $thumbnails . $basename;
  851. $part = empty($suffix) ? '.' : "-$suffix.";
  852.  
  853. $info = awpcp_utf8_pathinfo($original);
  854.  
  855. if ($suffix == 'original') {
  856. $alternatives = array($original);
  857. } else if ($suffix == 'large') {
  858. $alternatives = array(
  859. str_replace(".{$info['extension']}", "$part{$info['extension']}", $original),
  860. $original
  861. );
  862. } else {
  863. $alternatives = array(
  864. str_replace(".{$info['extension']}", "$part{$info['extension']}", $thumbnail),
  865. $thumbnail,
  866. $original
  867. );
  868. }
  869.  
  870. foreach ($alternatives as $imagepath) {
  871. if (file_exists(str_replace(AWPCPUPLOADURL, $uploads, $imagepath))) {
  872. return $imagepath;
  873. }
  874. }
  875.  
  876. return false;
  877. }
  878.  
  879. /**
  880. * Get the primary image of the given Ad.
  881. *
  882. * @param int $ad_id Ad's ID
  883. * @return object an StdClass object representing an image
  884. * @deprecated use awpcp_media_api()->get_ad_primary_image()
  885. */
  886. function awpcp_get_ad_primary_image($ad_id) {
  887. global $wpdb;
  888.  
  889. $query = 'SELECT * FROM ' . AWPCP_TABLE_ADPHOTOS . ' ';
  890. $query.= 'WHERE ad_id = %d AND is_primary = 1 AND disabled = 0';
  891.  
  892. $results = $wpdb->get_results($wpdb->prepare($query, $ad_id));
  893.  
  894. if (!empty($results)) return $results[0];
  895.  
  896. $query = 'SELECT * FROM ' . AWPCP_TABLE_ADPHOTOS . ' ';
  897. $query.= 'WHERE ad_id = %d AND disabled = 0 ORDER BY key_id LIMIT 0,1';
  898.  
  899. $results = $wpdb->get_results($wpdb->prepare($query, $ad_id));
  900.  
  901. return empty($results) ? null : $results[0];
  902. }
  903.  
  904.  
  905. function awpcp_array_insert($array, $index, $key, $item, $where='before') {
  906. $all = array_merge($array, array($key => $item));
  907. $keys = array_keys($array);
  908. $p = array_search($index, $keys);
  909.  
  910. if ($p !== FALSE) {
  911. if ($where === 'before')
  912. array_splice($keys, max($p, 0), 0, $key);
  913. else if ($where === 'after')
  914. array_splice($keys, min($p+1, count($keys)), 0, $key);
  915.  
  916. $array = array();
  917. // Create items array in proper order. The code below was the only
  918. // way I found to insert an item in an arbitrary position of an
  919. // array preserving keys. array_splice dropped the key of the inserted
  920. // value.
  921. foreach($keys as $key) {
  922. $array[$key] = $all[$key];
  923. }
  924. }
  925.  
  926. return $array;
  927. }
  928.  
  929. function awpcp_array_insert_before($array, $index, $key, $item) {
  930. return awpcp_array_insert($array, $index, $key, $item, 'before');
  931. }
  932.  
  933. function awpcp_array_insert_after($array, $index, $key, $item) {
  934. return awpcp_array_insert($array, $index, $key, $item, 'after');
  935. }
  936.  
  937. /**
  938. * @since 3.7.6
  939. */
  940. function awpcp_array_insert_first( $array, $item_key, $item ) {
  941. $all_keys = array_keys( $array );
  942. $first_key = array_shift( $all_keys );
  943.  
  944. return awpcp_array_insert( $array, $first_key, $item_key, $item, 'before' );
  945. }
  946.  
  947. /**
  948. * Inserts a menu item after one of the existing items.
  949. *
  950. * This function should be used by plugins when handling
  951. * the awpcp_menu_items filter.
  952. *
  953. * @param $items array Existing items
  954. * @param $after string key of item we want to place the new
  955. * item after
  956. * @param $key string New item's key
  957. * @param $item array New item's description
  958. */
  959. function awpcp_insert_menu_item($items, $after, $key, $item) {
  960. return awpcp_array_insert_after($items, $after, $key, $item);
  961. }
  962.  
  963. /**
  964. * Insert a submenu item in a WordPress admin menu, after an
  965. * existing item.
  966. *
  967. * Menu item should have already been added using add_submenu_page
  968. * or a similar function.
  969. *
  970. * @param $slug string Slug for the item to insert.
  971. * @param $after string Slug of the item to insert after.
  972. */
  973. function awpcp_insert_submenu_item_after($menu, $slug, $after) {
  974. global $submenu;
  975.  
  976. $items = isset($submenu[$menu]) ? $submenu[$menu] : array();
  977. $to = -1; $from = -1;
  978.  
  979. foreach ($items as $k => $item) {
  980. // insert after Fees
  981. if (strcmp($item[2], $after) === 0)
  982. $to = $k;
  983. if (strcmp($item[2], $slug) === 0)
  984. $from = $k;
  985. }
  986.  
  987. if ($to >= 0 && $from >= 0) {
  988. array_splice($items, $to + 1, 0, array($items[$from]));
  989. // current was added at the end of the array using add_submenu_page
  990. unset($items[$from + 1]);
  991. // use array_filter to restore array keys
  992. $submenu[$menu] = array_filter($items);
  993. }
  994. }
  995.  
  996. /**
  997. * @since 2.1.4
  998. */
  999. function awpcp_get_page_name($pagename) {
  1000. return get_awpcp_option($pagename);
  1001. }
  1002.  
  1003. /**
  1004. * @since 3.0.2
  1005. */
  1006. function awpcp_get_renew_ad_hash( $ad_id ) {
  1007. return md5( sprintf( 'renew-ad-%d-%s', $ad_id, wp_salt() ) );
  1008. }
  1009.  
  1010. /**
  1011. * @since 3.0.2
  1012. */
  1013. function awpcp_verify_renew_ad_hash( $ad_id, $hash ) {
  1014. return strcmp( awpcp_get_renew_ad_hash( $ad_id ), $hash ) === 0;
  1015. }
  1016.  
  1017. /**
  1018. * @since 3.0.2
  1019. */
  1020. function awpcp_get_email_verification_hash( $ad_id ) {
  1021. return wp_hash( sprintf( 'verify-%d', $ad_id ) );
  1022. }
  1023.  
  1024. /**
  1025. * @since 3.0.2
  1026. */
  1027. function awpcp_verify_email_verification_hash( $ad_id, $hash ) {
  1028. return strcmp( awpcp_get_email_verification_hash( $ad_id ) , $hash ) === 0;
  1029. }
  1030.  
  1031. /**
  1032. * @since 3.0-beta
  1033. */
  1034. function awpcp_get_blog_name($decode_html=true) {
  1035. $blog_name = get_option('blogname');
  1036.  
  1037. if (empty($blog_name)) {
  1038. $blog_name = _x('Classifieds Website', 'default blog title', 'another-wordpress-classifieds-plugin');
  1039. }
  1040.  
  1041. if ( $decode_html ) {
  1042. $blog_name = html_entity_decode( $blog_name, ENT_QUOTES, 'UTF-8' );
  1043. }
  1044.  
  1045. return $blog_name;
  1046. }
  1047.  
  1048. /**
  1049. * Use AWPCP_Request::post_param when possible.
  1050. */
  1051. function awpcp_post_param($name, $default='') {
  1052. return awpcp_array_data($name, $default, $_POST);
  1053. }
  1054.  
  1055. /**
  1056. * Use AWPCP_Request::param when possible.
  1057. */
  1058. function awpcp_request_param($name, $default='', $from=null) {
  1059. return awpcp_array_data($name, $default, is_null($from) ? $_REQUEST : $from);
  1060. }
  1061.  
  1062. function awpcp_array_data($name, $default, $from=array()) {
  1063. $value = isset($from[$name]) ? $from[$name] : null;
  1064.  
  1065. if (is_array($value) && count($value) > 0) {
  1066. return $value;
  1067. } else if (!empty($value)) {
  1068. return $value;
  1069. }
  1070.  
  1071. return $default;
  1072. }
  1073.  
  1074. /**
  1075. * Taken and adapted from: http://stackoverflow.com/a/6795671/201354
  1076. */
  1077. function awpcp_array_filter_recursive( $input, $callback = null ) {
  1078. foreach ( $input as &$value ) {
  1079. if ( is_array( $value ) ) {
  1080. $value = awpcp_array_filter_recursive( $value, $callback );
  1081. }
  1082. }
  1083.  
  1084. if ( is_callable( $callback ) ) {
  1085. return array_filter( $input, $callback );
  1086. } else {
  1087. return array_filter( $input );
  1088. }
  1089. }
  1090.  
  1091. /**
  1092. * Alternative to array_merge_recursive that keeps numeric keys.
  1093. *
  1094. * @since 3.4
  1095. */
  1096. function awpcp_array_merge_recursive( $a, $b ) {
  1097. $merged = $a;
  1098.  
  1099. foreach ( $b as $key => $value ) {
  1100. if ( isset( $merged[ $key ] ) && is_array( $merged[$key] ) && is_array( $value ) ) {
  1101. $merged[ $key ] = awpcp_array_merge_recursive( $merged[ $key ], $value );
  1102. } else {
  1103. $merged[ $key ] = $value;
  1104. }
  1105. }
  1106.  
  1107. return $merged;
  1108. }
  1109.  
  1110. function awpcp_get_property($object, $property, $default='') {
  1111. if ( is_object( $object ) && ( isset( $object->$property ) || array_key_exists( $property, get_object_vars( $object ) ) ) ) {
  1112. return $object->$property;
  1113. } else if ( is_array( $object ) && isset( $object[ $property ] ) ) {
  1114. return $object[ $property ];
  1115. }
  1116. return $default;
  1117. }
  1118.  
  1119. function awpcp_get_properties($objects, $property, $default='') {
  1120. $results = array();
  1121. foreach ($objects as $object) {
  1122. $results[] = awpcp_get_property($object, $property, $default);
  1123. }
  1124. return $results;
  1125. }
  1126.  
  1127. function awpcp_get_object_property_from_alternatives( $object, $alternatives, $default = '' ) {
  1128. foreach ( (array) $alternatives as $key ) {
  1129. $value = awpcp_get_property( $object, $key );
  1130.  
  1131. if ( strlen( $value ) == 0 ) {
  1132. continue;
  1133. }
  1134.  
  1135. return $value;
  1136. }
  1137.  
  1138. return $default;
  1139. }
  1140.  
  1141. /**
  1142. * Input:
  1143. * Array
  1144. * (
  1145. * [a] => dosearch
  1146. * [keywordphrase] =>
  1147. * [searchcategory] =>
  1148. * [searchname] =>
  1149. * [searchpricemin] => 0
  1150. * [searchpricemax] => 0
  1151. * [regions] => Array
  1152. * (
  1153. * [0] => Array
  1154. * (
  1155. * [country] => Colombia
  1156. * [state] => Boyacá
  1157. * [city] => Tunja
  1158. * )
  1159. *
  1160. * [1] => Array
  1161. * (
  1162. * [country] => Colombia
  1163. * [state] => Antioquia
  1164. * [city] => Medellín
  1165. * )
  1166. *
  1167. * [2] => Array
  1168. * (
  1169. * [country] => Colombia
  1170. * [state] => Boyacá
  1171. * [city] => Tunja
  1172. * )
  1173. *
  1174. * )
  1175. *
  1176. * [awpcp-test-min] =>
  1177. * [awpcp-test-max] =>
  1178. * [awpcp-select_list] =>
  1179. * )
  1180. *
  1181. * Output:
  1182. * Array
  1183. * (
  1184. * [a] => dosearch
  1185. * [keywordphrase] =>
  1186. * [searchcategory] =>
  1187. * [searchname] =>
  1188. * [searchpricemin] => 0
  1189. * [searchpricemax] => 0
  1190. * [regions[0][country]] => Colombia
  1191. * [regions[0][state]] => Boyacá
  1192. * [regions[0][city]] => Tunja
  1193. * [regions[1][country]] => Colombia
  1194. * [regions[1][state]] => Antioquia
  1195. * [regions[1][city]] => Medellín
  1196. * [regions[2][country]] => Colombia
  1197. * [regions[2][state]] => Boyacá
  1198. * [regions[2][city]] => Tunja
  1199. * [awpcp-test-min] =>
  1200. * [awpcp-test-max] =>
  1201. * [awpcp-select_list] =>
  1202. * )
  1203. * TODO: see WP's _http_build_query
  1204. *
  1205. * @since 3.0.2
  1206. */
  1207. function awpcp_flatten_array($array) {
  1208. if ( is_array( $array ) ) {
  1209. $flat = array();
  1210. _awpcp_flatten_array( $array, array(), $flat );
  1211. return $flat;
  1212. } else {
  1213. return $array;
  1214. }
  1215. }
  1216.  
  1217. /**
  1218. * @since 3.0.2
  1219. */
  1220. function _awpcp_flatten_array($array, $path=array(), &$return=array()) {
  1221. if ( is_array( $array ) ) {
  1222. foreach ( $array as $key => $value) {
  1223. _awpcp_flatten_array( $value, array_merge( $path, array( $key ) ), $return );
  1224. }
  1225. } else if ( count( $path ) > 0 ){
  1226. $first = $path[0];
  1227. if ( count( $path ) > 1 ) {
  1228. $return[ $first . '[' . join('][', array_slice( $path, 1 ) ) . ']'] = $array;
  1229. } else {
  1230. $return[ $first ] = $array;
  1231. }
  1232. }
  1233. }
  1234.  
  1235.  
  1236. /**
  1237. * Parses 'yes', 'true', 'no', 'false', 0, 1 into bool values.
  1238. *
  1239. * @since 2.1.3
  1240. * @param mixed $value value to parse
  1241. * @return bool
  1242. */
  1243. function awpcp_parse_bool($value) {
  1244. $lower = strtolower($value);
  1245. if ($lower === 'true' || $lower === 'yes')
  1246. return true;
  1247. if ($lower === 'false' || $lower === 'no')
  1248. return false;
  1249. return $value ? true : false;
  1250. }
  1251.  
  1252. function awpcp_get_currency_code() {
  1253. $currency_code = get_awpcp_option( ''. 'currency-code' );
  1254.  
  1255. if ( function_exists( 'mb_strtoupper' ) ) {
  1256. return mb_strtoupper( $currency_code );
  1257. } else {
  1258. return strtoupper( $currency_code );
  1259. }
  1260. }
  1261.  
  1262.  
  1263. /**
  1264. * XXX: Referenced in FAQ: http://awpcp.com/forum/faq/why-doesnt-my-currency-code-change-when-i-set-it/
  1265. */
  1266. function awpcp_get_currency_symbol() {
  1267. $currency_symbol = get_awpcp_option( 'currency-symbol' );
  1268.  
  1269. if ( ! empty( $currency_symbol ) ) {
  1270. return $currency_symbol;
  1271. }
  1272.  
  1273. $currency_code = awpcp_get_currency_code();
  1274.  
  1275. foreach ( awpcp_currency_symbols() as $currency_symbol => $currency_codes ) {
  1276. if ( in_array( $currency_code, $currency_codes ) ) {
  1277. return $currency_symbol;
  1278. }
  1279. }
  1280.  
  1281. return $currency_code;
  1282. }
  1283.  
  1284. /**
  1285. * @since 3.4
  1286. */
  1287. function awpcp_currency_symbols() {
  1288. return array(
  1289. '$' => array( 'CAD', 'AUD', 'NZD', 'SGD', 'HKD', 'USD', 'MXN' ),
  1290. '¥' => array( 'JPY' ),
  1291. '€' => array( 'EUR' ),
  1292. '£' => array( 'GBP' ),
  1293. '₽;' => array( 'RUB' ),
  1294. 'R$' => array( 'BRL' ),
  1295. 'Kč' => array( 'CZK' ),
  1296. 'kr.' => array( 'DKK' ),
  1297. '₪' => array( 'ILS' ),
  1298. 'RM' => array( 'MYR' ),
  1299. 'kr' => array( 'NOK', 'SEK' ),
  1300. '₱' => array( 'PHP' ),
  1301. 'CHF' => array( 'CHF' ),
  1302. 'NT$' => array( 'TWD' ),
  1303. '฿' => array( 'THB' ),
  1304. '₺' => array( 'TRY' ),
  1305. );
  1306. }
  1307.  
  1308. /**
  1309. * @since 3.0
  1310. */
  1311. function awpcp_format_money($value) {
  1312. if ( get_awpcp_option( 'show-currency-symbol' ) != 'do-not-show-currency-symbol' ) {
  1313. $show_currency_symbol = true;
  1314. } else {
  1315. $show_currency_symbol = false;
  1316. }
  1317.  
  1318. return awpcp_get_formmatted_amount( $value, $show_currency_symbol );
  1319. }
  1320.  
  1321. function awpcp_format_money_without_currency_symbol( $value ) {
  1322. return awpcp_get_formmatted_amount( $value, false );
  1323. }
  1324.  
  1325. function awpcp_get_formmatted_amount( $value, $include_symbol ) {
  1326. $symbol_position = get_awpcp_option( 'show-currency-symbol' );
  1327. $symbol = $include_symbol ? awpcp_get_currency_symbol() : '';
  1328.  
  1329. if ( get_awpcp_option( 'include-space-between-currency-symbol-and-amount' ) ) {
  1330. $separator = ' ';
  1331. } else {
  1332. $separator = '';
  1333. }
  1334.  
  1335. if ( $include_symbol && $symbol_position == 'show-currency-symbol-on-left' ) {
  1336. $formatted = '<currenct-symbol><separator><amount>';
  1337. } else if ( $include_symbol && $symbol_position == 'show-currency-symbol-on-right' ) {
  1338. $formatted = '<amount><separator><currenct-symbol>';
  1339. } else {
  1340. $formatted = '<amount>';
  1341. }
  1342.  
  1343. $formatted = str_replace( '<currenct-symbol>', $symbol, $formatted );
  1344. $formatted = str_replace( '<amount>', awpcp_format_number( $value ), $formatted );
  1345. $formatted = str_replace( '<separator>', $separator, $formatted );
  1346.  
  1347. return $value >= 0 ? $formatted : "($formatted)";
  1348. }
  1349.  
  1350. function awpcp_format_number( $value, $decimals = null ) {
  1351. return awpcp_get_formatted_number( $value, $decimals = get_awpcp_option( 'show-decimals' ) ? 2 : 0 );
  1352. }
  1353.  
  1354. function awpcp_get_formatted_number( $value, $decimals = 0 ) {
  1355. $thousands_separator = get_awpcp_option( 'thousands-separator' );
  1356. $decimal_separator = get_awpcp_option( 'decimal-separator' );
  1357.  
  1358. $formatted = number_format( abs( $value ), $decimals, '~', '^' );
  1359. $formatted = str_replace( '~', $decimal_separator, $formatted );
  1360. $formatted = str_replace( '^', $thousands_separator, $formatted );
  1361.  
  1362. return $formatted;
  1363. }
  1364.  
  1365. function awpcp_format_integer( $value ) {
  1366. return awpcp_get_formatted_number( $value, $decimals = 0 );
  1367. }
  1368.  
  1369. /**
  1370. * @since 3.7.5
  1371. */
  1372. function awpcp_parse_number( $value, $decimal_separator = false, $thousands_separator = false ) {
  1373. if ( strlen( $value ) === 0 ) return false;
  1374.  
  1375. $thousands_separator = $thousands_separator ? $thousands_separator : get_awpcp_option('thousands-separator');
  1376. $decimal_separator = $decimal_separator ? $decimal_separator : get_awpcp_option('decimal-separator');
  1377.  
  1378. $pattern = '/^-?(?:\d+|\d{1,3}(?:' . preg_quote( $thousands_separator ) . '\\d{3})+)?(?:' . preg_quote( $decimal_separator ) . '\\d+)?$/';
  1379.  
  1380. if ( preg_match( $pattern, $value ) ) {
  1381. $value = str_replace($thousands_separator, '', $value);
  1382. $value = str_replace($decimal_separator, '.', $value);
  1383. $number = floatval($value);
  1384. } else {
  1385. $number = false;
  1386. }
  1387.  
  1388. return $number;
  1389. }
  1390.  
  1391. /**
  1392. * @since 3.0
  1393. */
  1394. function awpcp_parse_money($value, $decimal_separator=false, $thousands_separator=false) {
  1395. return awpcp_parse_number( $value, $decimal_separator, $thousands_separator );
  1396. }
  1397.  
  1398.  
  1399. /**
  1400. * @since 2.1.4
  1401. */
  1402. function awpcp_get_flash_messages() {
  1403. if ( ! is_user_logged_in() ) {
  1404. return array();
  1405. }
  1406.  
  1407. if ( $messages = get_user_option( 'awpcp-messages', get_current_user_id() ) ) {
  1408. return $messages;
  1409. }
  1410.  
  1411. return array();
  1412. }
  1413.  
  1414. /**
  1415. * @since 2.1.4
  1416. */
  1417. function awpcp_update_flash_messages($messages) {
  1418. if (is_user_logged_in()) {
  1419. return update_user_option(get_current_user_id(), 'awpcp-messages', $messages);
  1420. } else {
  1421. return true;
  1422. }
  1423. }
  1424.  
  1425. /**
  1426. * @since 2.1.4
  1427. */
  1428. function awpcp_clear_flash_messages() {
  1429. if ( ! is_user_logged_in() ) {
  1430. return true;
  1431. }
  1432.  
  1433. return delete_user_option( get_current_user_id(), 'awpcp-messages' );
  1434. }
  1435.  
  1436. function awpcp_flash( $message, $class = array( 'awpcp-updated', 'updated') ) {
  1437. $messages = awpcp_get_flash_messages();
  1438.  
  1439. if ( ! awpcp_is_duplicated_flash_message( $messages, $message, $class ) ) {
  1440. $messages[] = array( 'message' => $message, 'class' => (array) $class );
  1441. awpcp_update_flash_messages( $messages );
  1442. }
  1443. }
  1444.  
  1445. function awpcp_is_duplicated_flash_message( $messages, $message, $class ) {
  1446. foreach ( $messages as $m ) {
  1447. if ( strcmp( $m['message'], $message ) == 0 ) {
  1448. return true;
  1449. }
  1450. }
  1451.  
  1452. return false;
  1453. }
  1454.  
  1455. /**
  1456. */
  1457. function awpcp_print_messages() {
  1458. // The function is expected to be called only once per request. However,
  1459. // due to special circumstances it is possible that the function is called
  1460. // twice or more, usually with the results from the last call being the ones
  1461. // shown to the user. In those cases, the messages would be lost unless we
  1462. // cache the messages during the request. That's why we use a static $messages
  1463. // variable.
  1464. static $messages = null;
  1465. $messages = is_null($messages) ? awpcp_get_flash_messages() : $messages;
  1466.  
  1467. foreach ($messages as $message) {
  1468. echo awpcp_print_message($message['message'], $message['class']);
  1469. }
  1470.  
  1471. awpcp_clear_flash_messages();
  1472. }
  1473.  
  1474. function awpcp_print_form_errors( $errors ) {
  1475. foreach ( $errors as $index => $error ) {
  1476. if ( is_numeric( $index ) ) {
  1477. echo awpcp_print_message( $error, array( 'awpcp-error', 'notice', 'notice-error' ) );
  1478. } else {
  1479. echo awpcp_print_message( $error, array( 'awpcp-error', 'notice', 'notice-error', 'ghost' ) );
  1480. }
  1481. }
  1482. }
  1483.  
  1484. function awpcp_print_message( $message, $class = array( 'awpcp-updated', 'notice', 'notice-info' ) ) {
  1485. $class = array_merge(array('awpcp-message'), $class);
  1486. return '<div class="' . join(' ', $class) . '"><p>' . $message . '</p></div>';
  1487. }
  1488.  
  1489. function awpcp_print_error($message) {
  1490. return awpcp_print_message($message, array('error'));
  1491. }
  1492.  
  1493. /**
  1494. * @since 3.7.4
  1495. */
  1496. function awpcp_render_warning( $message ) {
  1497. return awpcp_print_message( $message, array( 'awpcp-warning', 'notice', 'notice-warning' ) );
  1498. }
  1499.  
  1500. function awpcp_validate_error($field, $errors) {
  1501. $error = awpcp_array_data($field, '', $errors);
  1502. if (empty($error))
  1503. return '';
  1504. return '<label for="' . $field . '" generated="true" class="error" style="">' . $error . '</label>';
  1505. }
  1506.  
  1507. function awpcp_form_error($field, $errors) {
  1508. $error = awpcp_array_data($field, '', $errors);
  1509. return empty($error) ? '' : '<span class="awpcp-error">' . $error . '</span>';
  1510. }
  1511.  
  1512. function awpcp_form_help_text( $field_id, $help_text ) {
  1513. if ( empty( $help_text ) ) {
  1514. return null;
  1515. }
  1516.  
  1517. $params = wp_parse_args( $params, array(
  1518. 'text' => $help_text,
  1519. 'attributes' => array(
  1520. 'for' => $field_id,
  1521. 'class' => array( 'helptext', 'awpcp-form-helptext' ),
  1522. ),
  1523. ) );
  1524.  
  1525. return awpcp_html_label( $params );
  1526. }
  1527.  
  1528. function awpcp_attachment_background_color_explanation() {
  1529. if ( get_awpcp_option( 'imagesapprove' ) ) {
  1530. return '<p>' . __( 'The images or files with pale red background have been rejected by an administrator user. Likewise, files with a pale yellow background are awaiting approval. Files that are awaiting approval and rejected files, cannot be shown in the frontend.', 'another-wordpress-classifieds-plugin' ) . '</p>';
  1531. } else {
  1532. return '';
  1533. }
  1534. }
  1535.  
  1536. /**
  1537. * @since 3.0.2
  1538. * @deprecated since 3.2.3
  1539. */
  1540. function awpcp_module_not_compatible_notice( $module, $installed_version ) {
  1541. _deprecated_function( __FUNCTION__, '3.2.3', 'ModulesManager::show_module_not_compatible_notice()' );
  1542. global $awpcp_db_version;
  1543.  
  1544. $modules = awpcp()->get_premium_modules_information();
  1545.  
  1546. $name = $modules[ $module ][ 'name' ];
  1547. $required_version = $modules[ $module ][ 'required' ];
  1548.  
  1549. $message = __( 'This version of AWPCP %1$s module is not compatible with AWPCP version %2$s. Please get AWPCP %1$s %3$s or newer!', 'another-wordpress-classifieds-plugin' );
  1550. $message = sprintf( $message, '<strong>' . $name . '</strong>', $awpcp_db_version, '<strong>' . $required_version . '</strong>' );
  1551. $message = sprintf( '<strong>%s:</strong> %s', __( 'Error', 'another-wordpress-classifieds-plugin' ), $message );
  1552.  
  1553. return awpcp_print_error( $message );
  1554. }
  1555.  
  1556. /**
  1557. * Use awpcp_html_attributes instead.
  1558. *
  1559. * @deprecated since next-release
  1560. */
  1561. function awpcp_render_attributes($attrs) {
  1562. $attributes = array();
  1563. foreach ($attrs as $name => $value) {
  1564. if (is_array($value))
  1565. $value = join(' ', array_filter($value, 'strlen'));
  1566. $attributes[] = sprintf('%s="%s"', $name, esc_attr($value));
  1567. }
  1568. return join(' ', $attributes);
  1569. }
  1570.  
  1571. /**
  1572. * @since next-release
  1573. */
  1574. function awpcp_html_attributes( $attributes ) {
  1575. $output = array();
  1576.  
  1577. if ( isset( $attributes['class'] ) && is_array( $attributes['class'] ) ) {
  1578. $attributes['class'] = implode( ' ', array_filter( $attributes['class'], 'strlen' ) );
  1579. }
  1580.  
  1581. foreach ( $attributes as $name => $value ) {
  1582. $output[] = sprintf( '%s="%s"', $name, $value );
  1583. }
  1584.  
  1585. return implode( ' ', $output );
  1586. }
  1587.  
  1588. function awpcp_html_hidden_fields( $fields ) {
  1589. $output = array();
  1590.  
  1591. foreach ( array_filter( awpcp_flatten_array( $fields ) ) as $name => $value ) {
  1592. if ( is_object( $value ) ) {
  1593. continue;
  1594. }
  1595.  
  1596. $output[] = '<input type="hidden" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '" />';
  1597. }
  1598.  
  1599. return implode( "\n", $output );
  1600. }
  1601.  
  1602. /**
  1603. * @since next-release
  1604. */
  1605. function awpcp_html_image( $params ) {
  1606. $params = wp_parse_args( $params, array(
  1607. 'attributes' => array(
  1608. 'alt' => null,
  1609. 'title' => null,
  1610. 'src' => null,
  1611. 'width' => null,
  1612. 'height' => null,
  1613. 'style' => null,
  1614. ),
  1615. ) );
  1616.  
  1617. $attributes = rtrim( ' ' . awpcp_html_attributes( $params['attributes'] ) );
  1618. $element = str_replace( '<attributes>', $attributes, '<img<attributes>/>' );
  1619.  
  1620. return $element;
  1621. }
  1622.  
  1623. /**
  1624. * @since 3.6
  1625. */
  1626. function awpcp_html_label( $params ) {
  1627. $params = wp_parse_args( $params, array(
  1628. 'text' => null,
  1629. 'attributes' => array(
  1630. 'for' => null,
  1631. ),
  1632. ) );
  1633.  
  1634. $attributes = rtrim( ' ' . awpcp_html_attributes( $params['attributes'] ) );
  1635.  
  1636. $element = '<label <attributes>><text></label>';
  1637. $element = str_replace( '<attributes>', $attributes, $element );
  1638. $element = str_replace( '<text>', $params['text'], $element );
  1639.  
  1640. return $element;
  1641. }
  1642.  
  1643. /**
  1644. * @since 3.6
  1645. */
  1646. function awpcp_html_text_field( $params ) {
  1647. $params = awpcp_parse_html_params(
  1648. $params,
  1649. array(
  1650. 'required' => null,
  1651. 'readonly' => null,
  1652. )
  1653. );
  1654.  
  1655. if ( $params['readonly'] ) {
  1656. $attributes['readonly'] = 'readonly';
  1657. }
  1658.  
  1659. $params['attributes']['type'] = 'text';
  1660.  
  1661. return awpcp_html_input( $params );
  1662. }
  1663.  
  1664. /**
  1665. * @since 3.6
  1666. */
  1667. function awpcp_html_input( $params ) {
  1668. $attributes = rtrim( ' ' . awpcp_html_attributes( $params['attributes'] ) );
  1669. $element = str_replace( '<attributes>', $attributes, '<input <attributes>/>' );
  1670. return $element;
  1671. }
  1672.  
  1673. /**
  1674. * @since 3.6
  1675. */
  1676. function awpcp_html_radio( $params ) {
  1677. $params = awpcp_parse_html_params(
  1678. $params,
  1679. array(
  1680. 'current-value' => null,
  1681. 'disabled' => null,
  1682. ),
  1683. array(
  1684. 'value' => null,
  1685. )
  1686. );
  1687.  
  1688. if ( $params['disabled'] ) {
  1689. $params['attributes']['disabled'] = 'disabled';
  1690. }
  1691.  
  1692. if ( $params['current-value'] === $params['attributes']['value'] ) {
  1693. $params['attributes']['checked'] = 'checked';
  1694. }
  1695.  
  1696. $params['attributes']['type'] = 'radio';
  1697.  
  1698. return awpcp_html_input( $params );
  1699. }
  1700.  
  1701. /**
  1702. * @since 3.6
  1703. */
  1704. function awpcp_html_select( $params ) {
  1705. $params = awpcp_parse_html_params( $params );
  1706.  
  1707. $attributes = rtrim( ' ' . awpcp_html_attributes( $params['attributes'] ) );
  1708.  
  1709. $element = '<select <select-attributes>><options></select>';
  1710. $element = str_replace( '<select-attributes>', $attributes, $element );
  1711. $element = str_replace( '<options>', awpcp_html_options( $params ), $element );
  1712.  
  1713. return $element;
  1714. }
  1715.  
  1716. /**
  1717. * @since 3.6
  1718. */
  1719. function awpcp_html_options( $params ) {
  1720. $params = wp_parse_args( $params, array(
  1721. 'current-value' => null,
  1722. 'options' => array(),
  1723. ) );
  1724.  
  1725. $options = array();
  1726.  
  1727. foreach ( $params['options'] as $value => $text ) {
  1728. $option = '<option <attributes>><text></option>';
  1729.  
  1730. if ( strcmp( $value, $params['current-value'] ) === 0 ) {
  1731. $attributes = array( 'value' => $value, 'selected' => 'selected' );
  1732. } else {
  1733. $attributes = array( 'value' => $value );
  1734. }
  1735.  
  1736. $option = str_replace( '<attributes>', awpcp_html_attributes( $attributes ), $option );
  1737. $option = str_replace( '<text>', $text, $option );
  1738.  
  1739. $options[] = $option;
  1740. }
  1741.  
  1742. return implode( '', $options );
  1743. }
  1744.  
  1745. /**
  1746. * @since 3.6
  1747. */
  1748. function awpcp_parse_html_params( $params, $default_params = array(), $default_attributes = array() ) {
  1749. $params = wp_parse_args(
  1750. $params,
  1751. wp_parse_args(
  1752. $default_params,
  1753. array(
  1754. 'required' => null,
  1755. 'attributes' => array(),
  1756. )
  1757. )
  1758. );
  1759.  
  1760. $params['attributes'] = awpcp_parse_html_attributes( $params['attributes'], $default_attributes );
  1761.  
  1762. if ( $params['required'] ) {
  1763. $attributes['class'][] = 'required';
  1764. }
  1765.  
  1766. return $params;
  1767. }
  1768.  
  1769. function awpcp_parse_html_attributes( $attributes, $default_attributes = array() ) {
  1770. $attributes = wp_parse_args(
  1771. $attributes,
  1772. wp_parse_args(
  1773. $default_attributes,
  1774. array(
  1775. 'class' => array(),
  1776. )
  1777. )
  1778. );
  1779.  
  1780. if ( ! is_array( $attributes['class'] ) ) {
  1781. $attributes['class'] = explode( ' ', $attributes['class'] );
  1782. }
  1783.  
  1784. return $attributes;
  1785. }
  1786.  
  1787. /**
  1788. * @since 3.6
  1789. */
  1790. function awpcp_html_postbox_handle( $params ) {
  1791. $default_params = array(
  1792. 'heading_attributes' => array(),
  1793. 'span_attributes' => array(),
  1794. 'heading_class' => 'hndle',
  1795. 'heading_tag' => null,
  1796. 'content' => '',
  1797. );
  1798.  
  1799. $params = wp_parse_args( $params, $default_params );
  1800. $params['heading_attributes'] = awpcp_parse_html_attributes( $params['heading_attributes'] );
  1801. $params['span_attributes'] = awpcp_parse_html_attributes( $params['span_attributes'] );
  1802.  
  1803. if ( ! in_array( $params['heading_class'], $params['heading_attributes']['class'] ) ) {
  1804. $params['heading_attributes']['class'][] = $params['heading_class'];
  1805. }
  1806.  
  1807. if ( is_null( $params['heading_tag'] ) ) {
  1808. $params['heading_tag'] = awpcp_html_admin_second_level_heading_tag();
  1809. }
  1810.  
  1811. $element = '<<heading-tag> <heading-attributes>><span <span-attributes>><content></span></<heading-tag>>';
  1812. $element = str_replace( '<heading-tag>', $params['heading_tag'], $element );
  1813. $element = str_replace( '<heading-attributes>', awpcp_html_attributes( $params['heading_attributes'] ), $element );
  1814. $element = str_replace( '<span-attributes>', awpcp_html_attributes( $params['span_attributes'] ), $element );
  1815. $element = str_replace( '<content>', $params['content'], $element );
  1816.  
  1817. return $element;
  1818. }
  1819.  
  1820. /**
  1821. * @since 3.6
  1822. */
  1823. function awpcp_html_admin_first_level_heading( $params ) {
  1824. $params['tag'] = awpcp_html_admin_first_level_heading_tag();
  1825. return awpcp_html_heading( $params );
  1826. }
  1827.  
  1828. /**
  1829. * See:
  1830. * - https://make.wordpress.org/core/2015/07/31/headings-in-admin-screens-change-in-wordpress-4-3/
  1831. *
  1832. * @since 3.6
  1833. */
  1834. function awpcp_html_admin_first_level_heading_tag() {
  1835. if ( version_compare( get_bloginfo('version'), '4.3-beta1', '<' ) ) {
  1836. return 'h2';
  1837. } else {
  1838. return 'h1';
  1839. }
  1840. }
  1841.  
  1842. /**
  1843. * @since 3.6
  1844. */
  1845. function awpcp_html_admin_second_level_heading( $params ) {
  1846. $params['tag'] = awpcp_html_admin_second_level_heading_tag();
  1847. return awpcp_html_heading( $params );
  1848. }
  1849.  
  1850. /**
  1851. * See:
  1852. * - https://make.wordpress.org/core/2015/10/28/headings-hierarchy-changes-in-the-admin-screens/
  1853. *
  1854. * @since 3.6
  1855. */
  1856. function awpcp_html_admin_second_level_heading_tag() {
  1857. if ( version_compare( get_bloginfo('version'), '4.4-beta1', '<' ) ) {
  1858. return 'h3';
  1859. } else {
  1860. return 'h2';
  1861. }
  1862. }
  1863.  
  1864. /**
  1865. * @access private
  1866. * @since 3.6
  1867. */
  1868. function awpcp_html_heading( $params ) {
  1869. $default_params = array(
  1870. 'tag' => 'h1',
  1871. 'attributes' => array(),
  1872. 'content' => '',
  1873. );
  1874.  
  1875. $params = wp_parse_args( $params, $default_params );
  1876. $params['attributes'] = awpcp_parse_html_attributes( $params['attributes'] );
  1877.  
  1878. $element = '<<heading-tag> <heading-attributes>><content></<heading-tag>>';
  1879. $element = str_replace( '<heading-tag>', $params['tag'], $element );
  1880. $element = str_replace( '<heading-attributes>', awpcp_html_attributes( $params['attributes'] ), $element );
  1881. $element = str_replace( '<content>', $params['content'], $element );
  1882.  
  1883. return $element;
  1884. }
  1885.  
  1886. function awpcp_uploaded_file_error($file) {
  1887. $upload_errors = array(
  1888. UPLOAD_ERR_OK => __("No errors.", 'another-wordpress-classifieds-plugin'),
  1889. UPLOAD_ERR_INI_SIZE => __("The file is larger than upload_max_filesize.", 'another-wordpress-classifieds-plugin'),
  1890. UPLOAD_ERR_FORM_SIZE => __("The file is larger than form MAX_FILE_SIZE.", 'another-wordpress-classifieds-plugin'),
  1891. UPLOAD_ERR_PARTIAL => __("The file was only partially uploaded.", 'another-wordpress-classifieds-plugin'),
  1892. UPLOAD_ERR_NO_FILE => __("No file was uploaded.", 'another-wordpress-classifieds-plugin'),
  1893. UPLOAD_ERR_NO_TMP_DIR => __("Missing temporary directory.", 'another-wordpress-classifieds-plugin'),
  1894. UPLOAD_ERR_CANT_WRITE => __("Can't write file to disk.", 'another-wordpress-classifieds-plugin'),
  1895. UPLOAD_ERR_EXTENSION => __("The file upload was stopped by extension.", 'another-wordpress-classifieds-plugin')
  1896. );
  1897.  
  1898. return array($file['error'], $upload_errors[$file['error']]);
  1899. }
  1900.  
  1901. function awpcp_get_file_extension( $filename ) {
  1902. return strtolower( awpcp_utf8_pathinfo( $filename, PATHINFO_EXTENSION ) );
  1903. }
  1904.  
  1905. /**
  1906. * Recursively remove a directory.
  1907. * @since 3.0.2
  1908. */
  1909. function awpcp_rmdir($dir) {
  1910. if ( is_dir( $dir ) ) {
  1911. $objects = scandir( $dir );
  1912. foreach ( $objects as $object ) {
  1913. if ( $object != "." && $object != ".." ) {
  1914. if ( filetype( $dir . "/" . $object ) == "dir" ) {
  1915. awpcp_rmdir( $dir . "/" . $object );
  1916. } else {
  1917. unlink( $dir . "/" . $object );
  1918. }
  1919. }
  1920. }
  1921. reset( $objects );
  1922. rmdir( $dir );
  1923. }
  1924. }
  1925.  
  1926.  
  1927. /**
  1928. * @since 3.0.2
  1929. */
  1930. function awpcp_directory_permissions() {
  1931. return intval( get_awpcp_option( 'upload-directory-permissions', '0755' ), 8 );
  1932. }
  1933.  
  1934.  
  1935. /**
  1936. * @since 2.0.7
  1937. */
  1938. function awpcp_table_exists($table) {
  1939. global $wpdb;
  1940. $result = $wpdb->get_var("SHOW TABLES LIKE '" . $table . "'");
  1941. return strcasecmp($result, $table) === 0;
  1942. }
  1943.  
  1944. /**
  1945. * TODO: move memoization to where the information is needed. Having it here is the perfect
  1946. * scenarion for hard to track bugs.
  1947. * @since 2.1.4
  1948. */
  1949. function awpcp_column_exists($table, $column) {
  1950. static $column_exists = array();
  1951.  
  1952. if ( ! isset( $column_exists[ "$table-$column" ] ) ) {
  1953. $column_exists[ "$table-$column" ] = awpcp_check_if_column_exists( $table, $column );
  1954. }
  1955.  
  1956. return $column_exists[ "$table-$column" ];
  1957. }
  1958.  
  1959. /**
  1960. * @since 3.4
  1961. */
  1962. function awpcp_check_if_column_exists( $table, $column ) {
  1963. global $wpdb;
  1964.  
  1965. $suppress_errors = $wpdb->suppress_errors();
  1966. $result = $wpdb->query("SELECT `$column` FROM $table");
  1967. $wpdb->suppress_errors( $suppress_errors );
  1968.  
  1969. return $result !== false;
  1970. }
  1971.  
  1972.  
  1973. /** Email functions
  1974. ---------------------------------------------------------------------------- */
  1975.  
  1976. /**
  1977. * Extracted from class-phpmailer.php (PHPMailer::EncodeHeader).
  1978. *
  1979. * XXX: This may be necessary only for email addresses used in the Reply-To header.
  1980. *
  1981. * @since 3.0.2
  1982. */
  1983. function awpcp_encode_address_name($str) {
  1984. return awpcp_phpmailer()->encodeHeader( $str, 'phrase' );
  1985. }
  1986.  
  1987. /**
  1988. * Returns or creates an instance of PHPMailer.
  1989. *
  1990. * Extracted from wp_mail()'s code.
  1991. *
  1992. * @since 3.4
  1993. */
  1994. function awpcp_phpmailer() {
  1995. global $phpmailer;
  1996.  
  1997. // (Re)create it, if it's gone missing
  1998. if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) {
  1999. require_once ABSPATH . WPINC . '/class-phpmailer.php';
  2000. require_once ABSPATH . WPINC . '/class-smtp.php';
  2001. $phpmailer = new PHPMailer( true );
  2002. }
  2003.  
  2004. $phpmailer->CharSet = apply_filters( 'wp_mail_charset', get_bloginfo( 'charset' ) );
  2005.  
  2006. return $phpmailer;
  2007. }
  2008.  
  2009. /**
  2010. * @since 3.0.2
  2011. */
  2012. function awpcp_format_email_address($address, $name) {
  2013. return awpcp_encode_address_name( $name ) . " <" . $address . ">";
  2014. }
  2015.  
  2016. /**
  2017. * @since 3.7.1
  2018. */
  2019. function awpcp_format_recipient_address( $email_address, $name = false ) {
  2020. if ( $name && get_awpcp_option( 'include-recipient-name-in-email-address' ) ) {
  2021. return awpcp_format_email_address( $email_address, $name );
  2022. }
  2023.  
  2024. return $email_address;
  2025. }
  2026.  
  2027. /**
  2028. * Return the email address that should receive the notifications intented for
  2029. * administrator users.
  2030. *
  2031. * @since 3.0
  2032. * @return string email address
  2033. */
  2034. function awpcp_admin_recipient_email_address() {
  2035. $email_address = get_awpcp_option( 'admin-recipient-email' );
  2036. if ( empty( $email_address ) ) {
  2037. $email_address = get_option( 'admin_email' );
  2038. }
  2039.  
  2040. return $email_address;
  2041. }
  2042.  
  2043. /**
  2044. * Return the email address used as the sender for email notifications.
  2045. *
  2046. * @since 3.0
  2047. * @return string email address
  2048. */
  2049. function awpcp_admin_sender_email_address($include_contact_name=false) {
  2050. if ( awpcp_get_option( 'sent-emails-using-wordpress-email-address' ) ) {
  2051. $email_address = sprintf( 'wordpress@%s', awpcp_request()->domain( false ) );
  2052. } else if ( strlen( get_awpcp_option( 'awpcpadminemail' ) ) > 0 ) {
  2053. $email_address = get_awpcp_option( 'awpcpadminemail' );
  2054. } else {
  2055. $email_address = get_option( 'admin_email' );
  2056. }
  2057.  
  2058. return $email_address;
  2059. }
  2060.  
  2061. /**
  2062. * @since next-release
  2063. */
  2064. function awpcp_admin_sender_name() {
  2065. if ( awpcp_get_option( 'sent-emails-using-wordpress-email-address' ) ) {
  2066. $sender_name = 'WordPress';
  2067. } else {
  2068. $sender_name = awpcp_get_blog_name();
  2069. }
  2070.  
  2071. return $sender_name;
  2072. }
  2073.  
  2074. /**
  2075. * Return the name and email address of the account that appears as the sender in
  2076. * email notifications.
  2077. *
  2078. * @since 3.0
  2079. * @return string name <email@address>
  2080. */
  2081. function awpcp_admin_email_from() {
  2082. $email_address = awpcp_admin_sender_email_address();
  2083. $sender_name = awpcp_admin_sender_name();
  2084.  
  2085. return awpcp_format_email_address( $email_address, $sender_name );
  2086. }
  2087.  
  2088. /**
  2089. * Return the name and email address of the account that should receive notifications intented for
  2090. * administrator users.
  2091. *
  2092. * @since 3.0
  2093. * @return string name <email@address>
  2094. */
  2095. function awpcp_admin_email_to() {
  2096. return awpcp_format_recipient_address( awpcp_admin_recipient_email_address(), awpcp_get_blog_name() );
  2097. }
  2098.  
  2099. function awpcp_moderators_email_to() {
  2100. $email_addresses = array();
  2101.  
  2102. $users = awpcp_users_collection()->find( array(
  2103. 'fields' => array( 'public_name', 'user_email' ),
  2104. 'role' => 'awpcp-moderator'
  2105. ) );
  2106.  
  2107. foreach ( $users as $user ) {
  2108. $email_addresses[] = awpcp_format_recipient_address( $user->user_email, $user->public_name );
  2109. }
  2110.  
  2111. return $email_addresses;
  2112. }
  2113.  
  2114. /**
  2115. * @since 2.1.4
  2116. */
  2117. function awpcp_ad_enabled_email($ad) {
  2118. // user email
  2119. $mail = new AWPCP_Email;
  2120. $mail->to[] = awpcp_format_recipient_address( $ad->ad_contact_email, $ad->ad_contact_name );
  2121. $mail->subject = sprintf(__('Your Ad "%s" has been approved', 'another-wordpress-classifieds-plugin'), $ad->get_title());
  2122.  
  2123. $template = AWPCP_DIR . '/frontend/templates/email-ad-enabled-user.tpl.php';
  2124. $mail->prepare($template, compact('ad'));
  2125.  
  2126. $mail->send();
  2127. }
  2128.  
  2129. /**
  2130. * @since 3.0.2
  2131. */
  2132. function awpcp_ad_updated_user_email( $ad, $message ) {
  2133. $admin_email = awpcp_admin_recipient_email_address();
  2134.  
  2135. $mail = new AWPCP_Email;
  2136. $mail->to[] = awpcp_format_recipient_address( $ad->ad_contact_email, $ad->ad_contact_name );
  2137. $mail->subject = sprintf(__('Your Ad "%s" has been successfully updated', 'another-wordpress-classifieds-plugin'), $ad->get_title());
  2138.  
  2139. $template = AWPCP_DIR . '/frontend/templates/email-ad-updated-user.tpl.php';
  2140. $mail->prepare($template, compact('ad', 'message', 'admin_email'));
  2141.  
  2142. return $mail;
  2143. }
  2144.  
  2145.  
  2146. function awpcp_ad_updated_email( $ad, $message ) {
  2147. // user email
  2148. $mail = awpcp_ad_updated_user_email( $ad, $message );
  2149. return $mail->send();
  2150. }
  2151.  
  2152. function awpcp_ad_awaiting_approval_email($ad, $ad_approve, $images_approve) {
  2153. // admin email
  2154. $params = array( 'page' => 'awpcp-listings', 'action' => 'manage-images', 'id' => $ad->ad_id );
  2155. $manage_images_url = add_query_arg( urlencode_deep( $params ), admin_url( 'admin.php' ) );
  2156.  
  2157. if ( false == $ad_approve && $images_approve ) {
  2158. $subject = __( 'Images on Ad "%s" are awaiting approval', 'another-wordpress-classifieds-plugin' );
  2159.  
  2160. $message = __( 'Images on Ad "%s" are awaiting approval. You can approve the images going to the Manage Images section for that Ad and clicking the "Enable" button below each image. Click here to continue: %s.', 'another-wordpress-classifieds-plugin');
  2161. $messages = array( sprintf( $message, $ad->get_title(), $manage_images_url ) );
  2162. } else {
  2163. $subject = __( 'The Ad "%s" is awaiting approval', 'another-wordpress-classifieds-plugin' );
  2164.  
  2165. $message = __('The Ad "%s" is awaiting approval. You can approve the Ad going to the Manage Listings section and clicking the "Enable" action shown on top. Click here to continue: %s.', 'another-wordpress-classifieds-plugin');
  2166. $params = array('page' => 'awpcp-listings', 'action' => 'view', 'id' => $ad->ad_id);
  2167. $url = add_query_arg( urlencode_deep( $params ), admin_url( 'admin.php' ) );
  2168.  
  2169. $messages[] = sprintf( $message, $ad->get_title(), $url );
  2170.  
  2171. if ( $images_approve ) {
  2172. $message = __( 'Additionally, You can approve the images going to the Manage Images section for that Ad and clicking the "Enable" button below each image. Click here to continue: %s.', 'another-wordpress-classifieds-plugin' );
  2173. $messages[] = sprintf( $message, $manage_images_url );
  2174. }
  2175. }
  2176.  
  2177. $mail = new AWPCP_Email;
  2178. $mail->to[] = awpcp_admin_email_to();
  2179. $mail->subject = sprintf( $subject, $ad->get_title() );
  2180.  
  2181. $template = AWPCP_DIR . '/frontend/templates/email-ad-awaiting-approval-admin.tpl.php';
  2182. $mail->prepare( $template, compact( 'messages' ) );
  2183.  
  2184. $mail->send();
  2185. }
  2186.  
  2187. /** Table Helper related functions
  2188. ---------------------------------------------------------------------------- */
  2189.  
  2190. function awpcp_register_column_headers($screen, $columns, $sortable=array()) {
  2191. $wp_list_table = new AWPCP_List_Table($screen, $columns, $sortable);
  2192. }
  2193.  
  2194. function awpcp_print_column_headers($screen, $id = true, $sortable=array()) {
  2195. $wp_list_table = new AWPCP_List_Table($screen, array(), $sortable);
  2196. $wp_list_table->print_column_headers($id);
  2197. }
  2198.  
  2199. /**
  2200. * @since 3.3
  2201. */
  2202. function awpcp_enqueue_main_script() {
  2203. wp_enqueue_script( 'awpcp' );
  2204. }
  2205.  
  2206. /**
  2207. * @since 3.3
  2208. */
  2209. function awpcp_maybe_add_thickbox() {
  2210. if ( get_awpcp_option( 'awpcp_thickbox_disabled' ) ) {
  2211. return;
  2212. }
  2213.  
  2214. add_thickbox();
  2215. }
  2216.  
  2217.  
  2218. /**
  2219. * @since 3.2.1
  2220. */
  2221. function awpcp_load_plugin_textdomain( $__file__, $text_domain ) {
  2222. if ( awpcp_load_text_domain_with_file_prefix( $__file__, $text_domain, $text_domain ) ) {
  2223. return;
  2224. }
  2225.  
  2226. if ( $text_domain == 'another-wordpress-classifieds-plugin' ) {
  2227. // attempt to load translations from file using old text domain.
  2228. awpcp_load_text_domain_with_file_prefix( $__file__, $text_domain, 'AWPCP' );
  2229. }
  2230. }
  2231.  
  2232. /**
  2233. * TODO: Do we really need to load files from all those locations? Isn't all that verifications too exepensive?
  2234. * Also having all that options is confusing. We should support the standard ones only.
  2235. * @since 3.5.3.2
  2236. */
  2237. function awpcp_load_text_domain_with_file_prefix( $__file__, $text_domain, $file_prefix ) {
  2238. $basename = dirname( plugin_basename( $__file__ ) );
  2239. $locale = apply_filters( 'plugin_locale', get_locale(), $text_domain );
  2240. $text_domain_loaded = false;
  2241.  
  2242. // Load user translation from wp-content/languages/plugins/$domain-$locale.mo
  2243. $mofile = WP_LANG_DIR . '/plugins/' . $file_prefix . '-' . $locale . '.mo';
  2244. if ( file_exists( $mofile ) ) {
  2245. load_textdomain( $text_domain, $mofile );
  2246. $text_domain_loaded = awpcp_is_textdomain_loaded( $text_domain );
  2247. }
  2248.  
  2249. // Load user translation from wp-content/languages/another-wordpress-classifieds-plugin/$domain-$locale.mo
  2250. $mofile = WP_LANG_DIR . '/' . $basename . '/' . $file_prefix . '-' . $locale . '.mo';
  2251. if ( file_exists( $mofile ) ) {
  2252. load_textdomain( $text_domain, $mofile );
  2253. $text_domain_loaded = awpcp_is_textdomain_loaded( $text_domain ) || $text_domain_loaded;
  2254. }
  2255.  
  2256. // Load translation included in plugin's languages directory. Stop if the file is loaded.
  2257. $mofile = WP_PLUGIN_DIR . '/' . $basename . '/languages/' . $file_prefix . '-' . $locale . '.mo';
  2258. if ( file_exists( $mofile ) ) {
  2259. load_textdomain( $text_domain, $mofile );
  2260. $text_domain_loaded = awpcp_is_textdomain_loaded( $text_domain ) || $text_domain_loaded;
  2261. }
  2262.  
  2263. // Try loading the translations from the plugin's root directory.
  2264. $mofile = WP_PLUGIN_DIR . '/' . $basename . '/' . $file_prefix . '-' . $locale . '.mo';
  2265. if ( file_exists( $mofile ) ) {
  2266. load_textdomain( $text_domain, $mofile );
  2267. $text_domain_loaded = awpcp_is_textdomain_loaded( $text_domain ) || $text_domain_loaded;
  2268. }
  2269.  
  2270. return $text_domain_loaded;
  2271. }
  2272.  
  2273. /**
  2274. * @since 3.6.4
  2275. */
  2276. function awpcp_is_textdomain_loaded( $text_domain ) {
  2277. return ! is_a( get_translations_for_domain( $text_domain ), 'NOOP_Translations' );
  2278. }
  2279.  
  2280. function awpcp_utf8_strlen( $string ) {
  2281. if ( function_exists( 'mb_strlen' ) ) {
  2282. return mb_strlen( $string, 'UTF-8' );
  2283. } else {
  2284. return preg_match_all( '(.)su', $string, $matches );
  2285. }
  2286. }
  2287.  
  2288. function awpcp_utf8_substr( $string, $start, $length=null ) {
  2289. if ( function_exists( 'mb_substr' ) ) {
  2290. return mb_substr( $string, $start, $length, 'UTF-8' );
  2291. } else {
  2292. return awpcp_utf8_substr_pcre( $string, $start, $length );
  2293. }
  2294. }
  2295.  
  2296. function awpcp_utf8_substr_pcre( $string, $start, $length=null ) {
  2297. if ( is_null( $length ) ) {
  2298. $length = awpcp_utf8_strlen( $string ) - $start;
  2299. }
  2300.  
  2301. if ( preg_match_all( '/.{' . $start . '}(.{' . $length . '})/su', $string, $matches ) ) {
  2302. return $matches[1][0];
  2303. } else {
  2304. return '';
  2305. }
  2306. }
  2307.  
  2308. function awpcp_remove_utf8_non_characters( $content ) {
  2309. //remove EFBFBD (Replacement Character)
  2310. $content = trim( str_replace( "\xEF\xBF\xBD", '', $content ) );
  2311. // remove BOM character
  2312. $content = trim( str_replace( "\xEF\xBB\xBF", '', $content ) );
  2313. $content = trim( str_replace( "\xEF\xBF\xBE", '', $content ) );
  2314.  
  2315. return $content;
  2316. }
  2317.  
  2318. function awpcp_maybe_convert_to_utf8( $content ) {
  2319. if ( ! function_exists( 'iconv' ) ) {
  2320. return $content;
  2321. }
  2322.  
  2323. $encoding = awpcp_detect_encoding( $content );
  2324.  
  2325. if ( $encoding && 'UTF-8' != $encoding ) {
  2326. $converted_content = iconv( $encoding, 'UTF-8', $content );
  2327. } else {
  2328. $converted_content = $content;
  2329. }
  2330.  
  2331. return $converted_content;
  2332. }
  2333.  
  2334. /**
  2335. * @since 3.6
  2336. */
  2337. function awpcp_detect_encoding( $content ) {
  2338. static $encodings = array(
  2339. 'UTF-8', 'ASCII',
  2340. 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
  2341. 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10',
  2342. 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
  2343. 'Windows-1251', 'Windows-1252', 'Windows-1254',
  2344. );
  2345.  
  2346. if ( function_exists( 'mb_detect_encoding' ) ) {
  2347. return mb_detect_encoding( $content, $encodings, true );
  2348. } else {
  2349. return awpcp_mb_detect_encoding( $content, $encodings, true );
  2350. }
  2351. }
  2352.  
  2353. /**
  2354. * http://php.net/manual/en/function.mb-detect-encoding.php#113983
  2355. * @since 3.6.0
  2356. */
  2357. function awpcp_mb_detect_encoding( $conent, $encodings ) {
  2358. if ( ! function_exists( 'iconv' ) ) {
  2359. return false;
  2360. }
  2361.  
  2362. foreach ( $encodings as $encoding ) {
  2363. $sample = iconv( $encoding, $encoding, $string );
  2364. if ( md5( $sample ) == md5( $string ) ) {
  2365. return $encoding;
  2366. }
  2367. }
  2368.  
  2369. return false;
  2370. }
  2371.  
  2372. /**
  2373. * from http://stackoverflow.com/a/4459219/201354.
  2374. *
  2375. * @since 3.3
  2376. */
  2377. function awpcp_utf8_pathinfo( $path, $path_parts_types = null ) {
  2378. $modified_path = awpcp_add_path_prefix( $path );
  2379. $path_parts = is_null( $path_parts_types ) ? pathinfo( $modified_path ) : pathinfo( $modified_path, $path_parts_types );
  2380. $path_parts = awpcp_remove_path_prefix( $path_parts, $path_parts_types );
  2381.  
  2382. return $path_parts;
  2383. }
  2384.  
  2385. function awpcp_add_path_prefix( $path, $prefix = '_629353a' ) {
  2386. if ( strpos( $path, '/' ) === false ) {
  2387. $modified_path = $prefix . $path;
  2388. } else {
  2389. $modified_path = str_replace( '/', "/$prefix", $path );
  2390. }
  2391.  
  2392. return $modified_path;
  2393. }
  2394.  
  2395. function awpcp_remove_path_prefix( $path_parts, $path_part_type, $prefix = '_629353a' ) {
  2396. if ( is_array( $path_parts ) ) {
  2397. foreach ( $path_parts as $key => $value ) {
  2398. $path_parts[ $key ] = str_replace( $prefix, '', $value );
  2399. }
  2400. } else if ( is_string( $path_parts ) ) {
  2401. $path_parts = str_replace( $prefix, '', $path_parts );
  2402. }
  2403.  
  2404. return $path_parts;
  2405. }
  2406.  
  2407. function awpcp_utf8_basename( $path, $suffix = null ) {
  2408. $modified_path = awpcp_add_path_prefix( $path );
  2409. $basename = basename( $modified_path );
  2410. return awpcp_remove_path_prefix( $basename, PATHINFO_BASENAME );
  2411. }
  2412.  
  2413. /**
  2414. * TODO: provide a function that takes a path and one that doesn't. Remove
  2415. * file_exists; the former should only be called with valid paths.
  2416. *
  2417. * @param string $path Path to the file whose unique filename needs to be generated.
  2418. * @param string $filename Target filename. The unique filename will be as similar as
  2419. * possible to this name.
  2420. * @param array $directories The generated name must be unique in all directories in this array.
  2421. * @since 3.4
  2422. */
  2423. function awpcp_unique_filename( $path, $filename, $directories ) {
  2424. $pathinfo = awpcp_utf8_pathinfo( $filename );
  2425.  
  2426. $name = awpcp_sanitize_file_name( $pathinfo['filename'] );
  2427. $extension = $pathinfo['extension'];
  2428. $file_size = file_exists( $path ) ? filesize( $path ) : 0;
  2429. $timestamp = microtime();
  2430. $salt = wp_salt();
  2431. $counter = 0;
  2432.  
  2433. do {
  2434. $hash = hash( 'crc32b', "$name-$extension-$file_size-$timestamp-$salt-$counter" );
  2435. $new_filename = "$name-$hash.$extension";
  2436. $counter = $counter + 1;
  2437. } while ( awpcp_is_filename_already_used( $new_filename, $directories ) );
  2438.  
  2439. return $new_filename;
  2440. }
  2441.  
  2442. /**
  2443. * Remove characters not removed by sanitize_file_name, that are not invalid in OS,
  2444. * but cause problems with URLs.
  2445. *
  2446. * See: https://github.com/drodenbaugh/awpcp/issues/1222#issuecomment-119742743
  2447. *
  2448. * @since next-release
  2449. */
  2450. function awpcp_sanitize_file_name( $filename ) {
  2451. $sanitize_file_name = sanitize_file_name( $filename );
  2452. $sanitize_file_name = str_replace( '^', '', $sanitize_file_name );
  2453. return $sanitize_file_name;
  2454. }
  2455.  
  2456. /**
  2457. * @since 3.4
  2458. */
  2459. function awpcp_is_filename_already_used( $filename, $directories ) {
  2460. foreach ( $directories as $directory ) {
  2461. if ( file_exists( "$directory/$filename" ) ) {
  2462. return true;
  2463. }
  2464. }
  2465.  
  2466. return false;
  2467. }
  2468.  
  2469. /**
  2470. * @since 3.3
  2471. */
  2472. function awpcp_register_activation_hook( $__FILE__, $callback ) {
  2473. $file = WP_CONTENT_DIR . '/plugins/' . basename( dirname( $__FILE__ ) ) . '/' . basename( $__FILE__ );
  2474. register_activation_hook( $file, $callback );
  2475. }
  2476.  
  2477. function awpcp_register_deactivation_hook( $__FILE__, $callback ) {
  2478. $file = WP_CONTENT_DIR . '/plugins/' . basename( dirname( $__FILE__ ) ) . '/' . basename( $__FILE__ );
  2479. register_deactivation_hook( $file, $callback );
  2480. }
  2481.  
  2482. /**
  2483. * @since next-release
  2484. */
  2485. function awpcp_unregister_widget_if_exists( $widget_class ) {
  2486. global $wp_widget_factory;
  2487.  
  2488. if ( ! is_object( $wp_widget_factory ) ) {
  2489. return;
  2490. }
  2491.  
  2492. if ( isset( $wp_widget_factory->widgets[ 'AWPCP_LatestAdsWidget' ] ) ) {
  2493. unregister_widget("AWPCP_LatestAdsWidget");
  2494. }
  2495. }
  2496.  
  2497. /**
  2498. * @since 3.4
  2499. */
  2500. function awpcp_are_images_allowed() {
  2501. $allowed_image_extensions = array_filter( awpcp_get_option( 'allowed-image-extensions', array() ) );
  2502. return count( $allowed_image_extensions ) > 0;
  2503. }
  2504.  
  2505.  
  2506. function add_slashes_recursive( $variable ) {
  2507. if (is_string($variable)) {
  2508. return addslashes($variable);
  2509. } elseif (is_array($variable)) {
  2510. foreach($variable as $i => $value) {
  2511. $variable[$i] = add_slashes_recursive($value);
  2512. }
  2513. }
  2514.  
  2515. return $variable ;
  2516. }
  2517.  
  2518. function string_contains_string_at_position($haystack, $needle, $pos = 0, $case=true) {
  2519. if ($case) {
  2520. $result = (strpos($haystack, $needle, 0) === $pos);
  2521. } else {
  2522. $result = (stripos($haystack, $needle, 0) === $pos);
  2523. }
  2524. return $result;
  2525. }
  2526.  
  2527. function string_starts_with($haystack, $needle, $case=true) {
  2528. return string_contains_string_at_position($haystack, $needle, 0, $case);
  2529. }
  2530.  
  2531. function string_ends_with($haystack, $needle, $case=true) {
  2532. return string_contains_string_at_position($haystack, $needle, (strlen($haystack) - strlen($needle)), $case);
  2533. }
  2534.  
  2535. /**
  2536. * @since new-release
  2537. */
  2538. function awpcp_get_option( $option, $default = '', $reload = false ) {
  2539. return get_awpcp_option( $option, $default, $reload );
  2540. }
  2541.  
  2542. function get_awpcp_option($option, $default='', $reload=false) {
  2543. return awpcp()->settings->get_option( $option, $default, $reload );
  2544. }
  2545.  
  2546. //Function to replace addslashes_mq, which is causing major grief. Stripping of undesireable characters now done
  2547. // through above stripslashes_deep_gpc.
  2548. function clean_field($foo) {
  2549. return add_slashes_recursive($foo);
  2550. }
  2551. // END FUNCTION: replace underscores with dashes for search engine friendly urls
  2552.  
  2553.  
  2554. function isValidURL($url) {
  2555. return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
  2556. }
  2557.  
  2558. /**
  2559. * @since 3.0.2
  2560. */
  2561. function awpcp_is_valid_email_address($email) {
  2562. return filter_var( $email, FILTER_VALIDATE_EMAIL ) !== false;
  2563. }
  2564.  
  2565. /**
  2566. * @since 3.4
  2567. */
  2568. function awpcp_is_email_address_allowed( $email_address ) {
  2569. $wildcard = 'BCCsyfxU6HMXyyasic6t';
  2570. $pattern = '[a-zA-Z0-9-]*';
  2571.  
  2572. $domains_whitelist = str_replace( '*', $wildcard, get_awpcp_option( 'ad-poster-email-address-whitelist' ) );
  2573. $domains_whitelist = preg_quote( $domains_whitelist );
  2574. $domains_whitelist = str_replace( $wildcard, $pattern, $domains_whitelist );
  2575. $domains_whitelist = str_replace( "{$pattern}\.", "(?:{$pattern}\.)?", $domains_whitelist );
  2576. $domains_whitelist = array_filter( explode( "\n", $domains_whitelist ) );
  2577. $domains_whitelist = array_map( 'trim', $domains_whitelist );
  2578.  
  2579. $domains_pattern = '/' . implode( '|', $domains_whitelist ) . '/';
  2580.  
  2581. if ( empty( $domains_whitelist ) ) {
  2582. return true;
  2583. }
  2584.  
  2585. $domain = substr( $email_address, strpos( $email_address, '@' ) + 1 );
  2586.  
  2587. if ( preg_match( $domains_pattern, $domain ) ) {
  2588. return true;
  2589. }
  2590.  
  2591. return false;
  2592. }
  2593.  
  2594. function defaultcatexists($defid) {
  2595. global $wpdb;
  2596.  
  2597. $query = 'SELECT COUNT(*) FROM ' . AWPCP_TABLE_CATEGORIES . ' WHERE category_id = %d';
  2598. $query = $wpdb->prepare( $query, $defid );
  2599.  
  2600. $count = $wpdb->get_var( $query );
  2601.  
  2602. if ( $count !== false && $count > 0 ) {
  2603. return true;
  2604. } else {
  2605. return false;
  2606. }
  2607.  
  2608. }
  2609.  
  2610. // START FUNCTION: function to create a default category with an ID of 1 in the event a default category with ID 1 does not exist
  2611. function createdefaultcategory($idtomake,$titletocallit) {
  2612. global $wpdb;
  2613.  
  2614. $wpdb->insert( AWPCP_TABLE_CATEGORIES, array( 'category_name' => $titletocallit, 'category_parent_id' => 0 ) );
  2615.  
  2616. $query = 'UPDATE ' . AWPCP_TABLE_CATEGORIES . ' SET category_id = 1 WHERE category_id = %d';
  2617. $query = $wpdb->prepare( $query, $wpdb->insert_id );
  2618.  
  2619. $wpdb->query( $query );
  2620. }
  2621. // END FUNCTION: create default category
  2622.  
  2623.  
  2624. //////////////////////
  2625. // START FUNCTION: function to delete multiple ads at once used when admin deletes a category that contains ads but does not move the ads to a new category
  2626. //////////////////////
  2627. function massdeleteadsfromcategory($catid) {
  2628. $ads = AWPCP_Ad::find_by_category_id($catid);
  2629. foreach ($ads as $ad) {
  2630. $ad->delete();
  2631. }
  2632. }
  2633. // END FUNCTION
  2634.  
  2635. function create_ad_postedby_list($name) {
  2636. global $wpdb;
  2637.  
  2638. $output = '';
  2639. $query = 'SELECT DISTINCT ad_contact_name FROM ' . AWPCP_TABLE_ADS . ' WHERE disabled = 0 ORDER BY ad_contact_name ASC';
  2640.  
  2641. $results = $wpdb->get_col( $query );
  2642.  
  2643. foreach ( $results as $contact_name ) {
  2644. if ( strcmp( $contact_name, $name ) === 0 ) {
  2645. $output .= "<option value=\"$contact_name\" selected=\"selected\">$contact_name</option>";
  2646. } else {
  2647. $output .= "<option value=\"$contact_name\">$contact_name</option>";
  2648. }
  2649. }
  2650.  
  2651. return $output;
  2652. }
  2653.  
  2654. function awpcp_strip_html_tags( $text )
  2655. {
  2656. // Remove invisible content
  2657. $text = preg_replace(
  2658. array(
  2659. '@<head[^>]*?>.*?</head>@siu',
  2660. '@<style[^>]*?>.*?</style>@siu',
  2661. '@<script[^>]*?.*?</script>@siu',
  2662. '@<object[^>]*?.*?</object>@siu',
  2663. '@<embed[^>]*?.*?</embed>@siu',
  2664. '@<applet[^>]*?.*?</applet>@siu',
  2665. '@<noframes[^>]*?.*?</noframes>@siu',
  2666. '@<noscript[^>]*?.*?</noscript>@siu',
  2667. '@<noembed[^>]*?.*?</noembed>@siu',
  2668. // Add line breaks before and after blocks
  2669. '@</?((address)|(blockquote)|(center)|(del))@iu',
  2670. '@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
  2671. '@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
  2672. '@</?((table)|(th)|(td)|(caption))@iu',
  2673. '@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
  2674. '@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
  2675. '@</?((frameset)|(frame)|(iframe))@iu',
  2676. ),
  2677. array(
  2678. ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
  2679. "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
  2680. "\n\$0", "\n\$0",
  2681. ),
  2682. $text );
  2683. return strip_tags( $text );
  2684. }
  2685. // END FUNCTION
  2686.  
  2687. // Override the SMTP settings built into WP if the admin has enabled that feature
  2688. function awpcp_phpmailer_init_smtp( $phpmailer ) {
  2689. // smtp not enabled?
  2690. $enabled = get_awpcp_option('usesmtp');
  2691. if ( !$enabled || 0 == $enabled ) return;
  2692. $hostname = get_awpcp_option('smtphost');
  2693. $port = get_awpcp_option('smtpport');
  2694. $username = get_awpcp_option('smtpusername');
  2695. $password = get_awpcp_option('smtppassword');
  2696. // host and port not set? gotta have both.
  2697. if ( '' == trim( $hostname ) || '' == trim( $port ) )
  2698. return;
  2699. // still got defaults set? can't use those.
  2700. if ( 'mail.example.com' == trim( $hostname ) ) return;
  2701. if ( 'smtp_username' == trim( $username ) ) return;
  2702. $phpmailer->Mailer = 'smtp';
  2703. $phpmailer->Host = $hostname;
  2704. $phpmailer->Port = $port;
  2705. // If there's a username and password then assume SMTP Auth is necessary and set the vars:
  2706. if ( '' != trim( $username ) && '' != trim( $password ) ) {
  2707. $phpmailer->SMTPAuth = true;
  2708. $phpmailer->Username = $username;
  2709. $phpmailer->Password = $password;
  2710. }
  2711. // that's it!
  2712. }
  2713.  
  2714. /**
  2715. * @deprecated 3.7.5 Use AWPCP_Email class instead.
  2716. */
  2717. function awpcp_process_mail($senderemail='', $receiveremail='', $subject='',
  2718. $body='', $sendername='', $replytoemail='', $html=true)
  2719. {
  2720. $headers = "MIME-Version: 1.0\n" .
  2721. "From: $sendername <$senderemail>\n" .
  2722. "Reply-To: $replytoemail\n";
  2723.  
  2724. if ($html) {
  2725. $headers .= "Content-Type: text/html; charset=\"" . get_option('blog_charset') . "\"\n";
  2726. } else {
  2727. $headers .= "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
  2728. }
  2729.  
  2730. $subject = $subject;
  2731. $message = "$body\n\n" . awpcp_format_email_sent_datetime() . "\n\n";
  2732.  
  2733. if (wp_mail($receiveremail, $subject, $message, $headers )) {
  2734. return 1;
  2735.  
  2736. } elseif (awpcp_send_email($senderemail, $receiveremail, $subject, $body,true)) {
  2737. return 1;
  2738.  
  2739. } elseif (@mail($receiveremail, $subject, $body, $headers)) {
  2740. return 1;
  2741.  
  2742. } else {
  2743. return 0;
  2744. }
  2745. }
  2746.  
  2747. function awpcp_format_email_sent_datetime() {
  2748. $time = date_i18n( awpcp_get_datetime_format(), current_time( 'timestamp' ) );
  2749. return sprintf( __( 'Email sent %s.', 'another-wordpress-classifieds-plugin' ), $time );
  2750. }
  2751.  
  2752. // make sure the IP isn't a reserved IP address
  2753. function awpcp_validip($ip) {
  2754.  
  2755. if (!empty($ip) && ip2long($ip)!=-1) {
  2756.  
  2757. $reserved_ips = array (
  2758. array('0.0.0.0','2.255.255.255'),
  2759. array('10.0.0.0','10.255.255.255'),
  2760. array('127.0.0.0','127.255.255.255'),
  2761. array('169.254.0.0','169.254.255.255'),
  2762. array('172.16.0.0','172.31.255.255'),
  2763. array('192.0.2.0','192.0.2.255'),
  2764. array('192.168.0.0','192.168.255.255'),
  2765. array('255.255.255.0','255.255.255.255')
  2766. );
  2767.  
  2768. foreach ($reserved_ips as $r) {
  2769. $min = ip2long($r[0]);
  2770. $max = ip2long($r[1]);
  2771. if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max))
  2772. return false;
  2773. }
  2774.  
  2775. return true;
  2776.  
  2777. } else {
  2778.  
  2779. return false;
  2780.  
  2781. }
  2782. }
  2783.  
  2784. // retrieve the ad poster's IP if possible
  2785. function awpcp_getip() {
  2786. if ( awpcp_validip(awpcp_array_data("HTTP_CLIENT_IP", '', $_SERVER)) ) {
  2787. return $_SERVER["HTTP_CLIENT_IP"];
  2788. }
  2789.  
  2790. foreach ( explode(",", awpcp_array_data("HTTP_X_FORWARDED_FOR", '', $_SERVER)) as $ip ) {
  2791. if ( awpcp_validip(trim($ip) ) ) {
  2792. return $ip;
  2793. }
  2794. }
  2795.  
  2796. if (awpcp_validip(awpcp_array_data("HTTP_X_FORWARDED", '', $_SERVER))) {
  2797. return $_SERVER["HTTP_X_FORWARDED"];
  2798.  
  2799. } elseif (awpcp_validip(awpcp_array_data('HTTP_FORWARDED_FOR', '', $_SERVER))) {
  2800. return $_SERVER["HTTP_FORWARDED_FOR"];
  2801.  
  2802. } elseif (awpcp_validip(awpcp_array_data("HTTP_FORWARDED", '', $_SERVER))) {
  2803. return $_SERVER["HTTP_FORWARDED"];
  2804.  
  2805. } else {
  2806. return awpcp_array_data("REMOTE_ADDR", '', $_SERVER);
  2807. }
  2808. }
  2809.  
  2810. function awpcp_get_ad_share_info($id) {
  2811. global $wpdb;
  2812.  
  2813. $ad = AWPCP_Ad::find_by_id($id);
  2814. $info = array();
  2815.  
  2816. if (is_null($ad)) {
  2817. return null;
  2818. }
  2819.  
  2820. $info['url'] = url_showad($id);
  2821. $info['title'] = stripslashes($ad->ad_title);
  2822. $info['description'] = strip_tags(stripslashes($ad->ad_details));
  2823.  
  2824. $info['description'] = str_replace( array( "\r", "\n", "\t" ), ' ', $info['description'] );
  2825. $info['description'] = preg_replace( '/ {2,}/', ' ', $info['description'] );
  2826. $info['description'] = trim( $info['description'] );
  2827.  
  2828. if ( awpcp_utf8_strlen( $info['description'] ) > 300 ) {
  2829. $info['description'] = awpcp_utf8_substr( $info['description'], 0, 300 ) . '...';
  2830. }
  2831.  
  2832. $info['images'] = array();
  2833.  
  2834. $info['published-time'] = awpcp_datetime( 'Y-m-d', $ad->ad_postdate );
  2835. $info['modified-time'] = awpcp_datetime( 'Y-m-d', $ad->ad_last_updated );
  2836.  
  2837. $images = awpcp_media_api()->find_by_ad_id( $ad->ad_id, array(
  2838. 'enabled' => true,
  2839. 'status' => AWPCP_Media::STATUS_APPROVED,
  2840. ) );
  2841.  
  2842. foreach ( $images as $image ) {
  2843. $info[ 'images' ][] = $image->get_url( 'large' );
  2844. }
  2845.  
  2846. return $info;
  2847. }
  2848.  
  2849. /**
  2850. * TODO: move to AWPCP_Email?
  2851. */
  2852. function awpcp_send_email($from,$to,$subject,$message, $html=true, $attachments=array(), $bcc='') {
  2853. $separator='Next.Part.331925654896717'.time();
  2854. $att_separator='NextPart.is_a_file9817298743'.time();
  2855. $headers="From: $from\n";
  2856. $headers.="MIME-Version: 1.0\n";
  2857. if (!empty($bcc)) {
  2858. $headers.="Bcc: $bcc\n";
  2859. }
  2860. $text_header="Content-Type: text/plain; charset=\"iso-8859-1\"\nContent-Transfer-Encoding: 8bit\n\n";
  2861. $html_header="Content-Type: text/html; charset=\"iso-8859-1\"\nContent-Transfer-Encoding: 8bit\n\n";
  2862. $html_message=$message;
  2863. $text_message=$message;
  2864. $text_message=str_replace('&nbsp;',' ',$text_message);
  2865. $text_message=trim(strip_tags(stripslashes($text_message)));
  2866. // Bring down number of empty lines to 2 max
  2867. $text_message=preg_replace("/\n[\s]+\n/","\n",$text_message);
  2868. $text_message=preg_replace("/[\n]{3,}/", "\n\n",$text_message);
  2869. $text_message=wordwrap($text_message,72);
  2870. $message="\n\n--$separator\n".$text_header.$text_message;
  2871.  
  2872. if ($html) {
  2873. $message.="\n\n--$separator\n".$html_header.$html_message;
  2874. }
  2875.  
  2876. $message.="\n\n--$separator--\n";
  2877.  
  2878. if (!empty($attachments)) {
  2879. $headers.="Content-Type: multipart/mixed; boundary=\"$att_separator\";\n";
  2880. $message="\n\n--$att_separator\nContent-Type: multipart/alternative; boundary=\"$separator\";\n".$message;
  2881. while (list(,$file)=each($attachments)) {
  2882. $message.="\n\n--$att_separator\n";
  2883. $message.="Content-Type: application/octet-stream; name=\"".basename($file)."\"\n";
  2884. $message.="Content-Transfer-Encoding: base64\n";
  2885. $message.='Content-Disposition: attachment; filename="'.basename($file)."\"\n\n";
  2886. $message.=wordwrap(base64_encode(fread(fopen($file,'rb'),filesize($file))),72,"\n",1);
  2887. }
  2888. $message.="\n\n--$att_separator--\n";
  2889. } else {
  2890. $headers.="Content-Type: multipart/alternative;\n\tboundary=\"$separator\";\n";
  2891. }
  2892. $message='This is a multi-part message in MIME format.'.$message;
  2893. if (isset($_SERVER['WINDIR']) || isset($_SERVER['windir']) || isset($_ENV['WINDIR']) || isset($_ENV['windir'])) {
  2894. $message=unix2dos($message);
  2895. }
  2896. // $headers=unix2dos($headers);
  2897. $sentok=@mail($to,$subject,$message,$headers,"-f$from");
  2898. return $sentok;
  2899. }
  2900.  
  2901. /**
  2902. * @since 3.6.6
  2903. */
  2904. function awpcp_user_agent_header() {
  2905. $user_agent = "WordPress %s / Another WordPress Classifieds Plugin %s";
  2906. $user_agent = sprintf( $user_agent, get_bloginfo( 'version' ), $GLOBALS['awpcp_db_version'] );
  2907. return $user_agent;
  2908. }
  2909.  
  2910. /**
  2911. * @since 3.7.6
  2912. */
  2913. function awpcp_get_curl_info() {
  2914. if ( ! in_array( 'curl', get_loaded_extensions() ) ) {
  2915. return __( 'Not Installed', 'another-wordpress-classifieds-plugin' );
  2916. }
  2917.  
  2918. if ( ! function_exists( 'curl_version' ) ) {
  2919. return __( 'Installed', 'another-wordpress-classifieds-plugin' );
  2920. }
  2921.  
  2922. $curl_info = curl_version();
  2923.  
  2924. $output[] = "Version: {$curl_info['version']}";
  2925.  
  2926. if ( $curl_info['features'] & CURL_VERSION_SSL) {
  2927. $output[] = __( 'SSL Support: Yes.', 'another-wordpress-classifieds-plugin' );
  2928. } else {
  2929. $output[] = __( 'SSL Support: No.', 'another-wordpress-classifieds-plugin' );
  2930. }
  2931.  
  2932. $output[] = __( 'OpenSSL version:' ) . ' ' . $curl_info['ssl_version'];
  2933.  
  2934. return implode( '<br>', $output );
  2935. }
  2936.  
  2937. /**
  2938. * @since 3.7.8
  2939. */
  2940. function awpcp_get_server_ip_address() {
  2941. $ip_address = get_transient( 'awpcp-server-ip-address' );
  2942.  
  2943. if ( $ip_address ) {
  2944. return $ip_address;
  2945. }
  2946.  
  2947. $response = wp_remote_get( 'https://httpbin.org/ip' );
  2948.  
  2949. if ( is_wp_error( $response ) ) {
  2950. return $ip_address;
  2951. }
  2952.  
  2953. $body = json_decode( wp_remote_retrieve_body( $response ) );
  2954.  
  2955. if ( ! isset( $body->origin ) ) {
  2956. return $ip_address;
  2957. }
  2958.  
  2959. $ip_address = $body->origin;
  2960.  
  2961. if ( $ip_address ) {
  2962. set_transient( 'awpcp-server-ip-address', $ip_address, HOUR_IN_SECONDS );
  2963. }
  2964.  
  2965. return $ip_address;
  2966. }
Add Comment
Please, Sign In to add comment