Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wvega/395682884989a58a8d6a to your computer and use it in GitHub Desktop.
Save wvega/395682884989a58a8d6a to your computer and use it in GitHub Desktop.
Implementation of Pippin's WP Session for AWPCP
From 6557efdb0d8c840614706e9f6cb1921128bed363 Mon Sep 17 00:00:00 2001
From: Willington Vega <wvega@wvega.com>
Date: Fri, 12 Jun 2015 19:51:26 -0500
Subject: [PATCH] Use Pippin's WP_Session in AWPCP.
https://pippinsplugins.com/storing-session-data-in-wordpress-without-_session/
---
another-wordpress-classifieds-plugin/awpcp.php | 9 +-
.../includes/sessions/class-session-manager.php | 178 ++++++++++++++++
.../includes/sessions/class-session.php | 119 +++++++++++
.../includes/settings/class-general-settings.php | 9 +
.../wp-session/class-recursive-arrayaccess.php | 213 +++++++++++++++++++
.../vendors/wp-session/class-wp-session-utils.php | 135 +++++++++++++
.../vendors/wp-session/class-wp-session.php | 225 +++++++++++++++++++++
.../includes/class-location-service.php | 26 +--
8 files changed, 897 insertions(+), 17 deletions(-)
create mode 100644 another-wordpress-classifieds-plugin/includes/sessions/class-session-manager.php
create mode 100644 another-wordpress-classifieds-plugin/includes/sessions/class-session.php
create mode 100644 another-wordpress-classifieds-plugin/vendors/wp-session/class-recursive-arrayaccess.php
create mode 100644 another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session-utils.php
create mode 100644 another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session.php
diff --git a/another-wordpress-classifieds-plugin/awpcp.php b/another-wordpress-classifieds-plugin/awpcp.php
index 040a3f1..4b840cd 100644
--- a/another-wordpress-classifieds-plugin/awpcp.php
+++ b/another-wordpress-classifieds-plugin/awpcp.php
@@ -98,6 +98,8 @@ require_once(AWPCP_DIR . "/includes/compatibility/class-facebook-plugin-integrat
require_once( AWPCP_DIR . "/includes/compatibility/class-yoast-wordpress-seo-plugin-integration.php" );
require_once( AWPCP_DIR . "/includes/compatibility/class-woocommerce-plugin-integration.php" );
+require_once( AWPCP_DIR . "/includes/db/class-database-column-creator.php" );
+
require_once( AWPCP_DIR . "/includes/functions/settings.php" );
require_once( AWPCP_DIR . "/includes/form-fields/class-form-field.php" );
@@ -165,7 +167,8 @@ require_once(AWPCP_DIR . "/includes/models/category.php");
require_once(AWPCP_DIR . "/includes/models/image.php");
require_once(AWPCP_DIR . "/includes/models/payment-transaction.php");
-require_once( AWPCP_DIR . "/includes/db/class-database-column-creator.php" );
+require_once( AWPCP_DIR . "/includes/sessions/class-session-manager.php" );
+require_once( AWPCP_DIR . "/includes/sessions/class-session.php" );
require_once( AWPCP_DIR . "/includes/views/class-ajax-handler.php" );
require_once( AWPCP_DIR . "/includes/views/class-base-page.php" );
@@ -437,6 +440,10 @@ class AWPCP {
add_action( 'init', array($this, 'init' ));
add_action( 'init', array($this, 'register_custom_style'), 1000000 );
+ $session_manager = awpcp_session_manager();
+ add_action( 'init', array( $session_manager, 'start_session'), -1 );
+ add_action( 'shutdown', array( $session_manager, 'commit_session' ) );
+
add_action( 'admin_init', array( $this, 'check_compatibility_with_premium_modules' ) );
add_action('admin_notices', array($this, 'admin_notices'));
add_action( 'admin_notices', array( $this->modules_manager, 'show_admin_notices' ) );
diff --git a/another-wordpress-classifieds-plugin/includes/sessions/class-session-manager.php b/another-wordpress-classifieds-plugin/includes/sessions/class-session-manager.php
new file mode 100644
index 0000000..127e63c
--- /dev/null
+++ b/another-wordpress-classifieds-plugin/includes/sessions/class-session-manager.php
@@ -0,0 +1,178 @@
+<?php
+
+function awpcp_session_manager() {
+ static $instance;
+
+ if ( is_null( $instance ) ) {
+ $instance = new AWPCP_Session_Manager( awpcp()->settings, awpcp_request() );
+ }
+
+ return $instance;
+}
+
+function awpcp_session() {
+ $session = awpcp_session_manager()->get_session();
+
+ if ( is_null( $session ) ) {
+ _doing_it_wrong( __FUNCTION__, 'Trying to get the Classifieds Session before it was started.', '3.3.5' );
+ }
+
+ return $session;
+}
+
+/**
+ * Modified from https://github.com/easydigitaldownloads/Easy-Digital-Downloads/blob/master/includes/class-edd-session.php
+ *
+ * @since next-release
+ */
+class AWPCP_Session_Manager {
+
+ private $session;
+
+ private $settings;
+ private $request;
+
+ public function __construct( $settings, $request ) {
+ $this->settings = $settings;
+ $this->request = $request;
+ }
+
+ public function start_session() {
+ if ( $this->should_use_php_sessions() ) {
+ $this->session = $this->load_php_sessions_backend();
+ } else {
+ $this->session = $this->load_wp_session_backend();
+ }
+ }
+
+ /**
+ * Starts a new session if one hasn't started yet.
+ *
+ * Checks to see if the server supports PHP sessions
+ * or if the EDD_USE_PHP_SESSIONS constant is defined
+ *
+ * @return boolean $ret True if we are using PHP sessions, false otherwise
+ */
+ private function should_use_php_sessions() {
+ // If the database variable is already set, no need to run autodetection
+ $should_use_php_sessions = (bool) $this->settings->get_option( 'use-php-sessions' );
+
+ if ( ! $should_use_php_sessions ) {
+ if ( function_exists( 'session_start' ) && ! ini_get( 'safe_mode' ) ) {
+ if ( isset( $_SESSION ) ) {
+ $_SESSION['awpcp-use-php-sessions'] = true;
+ }
+
+ if ( isset( $_SESSION['awpcp-use-php-sessions'] ) && $_SESSION['awpcp-use-php-sessions'] ) {
+ $should_use_php_sessions = true;
+ $this->settings->update_option( $should_use_php_sessions );
+ }
+ }
+ }
+
+ return (bool) apply_filters( 'awpcp-use-php-sessions', $should_use_php_sessions );
+ }
+
+ private function load_php_sessions_backend() {
+ $this->maybe_start_php_session();
+
+ if ( is_multisite() ) {
+ $session_prefix = '_' . get_current_blog_id();
+ } else {
+ $session_prefix = '';
+ }
+
+ return new AWPCP_Session( new AWPCP_PHP_Session_Backend( $session_prefix ) );
+ }
+
+ private function maybe_start_php_session() {
+ $session_id = session_id();
+
+ if ( empty( $session_id ) && ! headers_sent() ) {
+ // if we are in a subdomain, let PHP choose the right domain
+ if ( strcmp( $this->request->domain(), $this->request->domain( false ) ) == 0 ) {
+ $domain = '';
+ // otherwise strip the www part
+ } else {
+ $domain = $this->request->domain( false, '.' );
+ }
+
+ @session_set_cookie_params( 0, '/', $domain, false, true );
+ @session_start();
+ }
+ }
+
+ private function load_wp_session_backend() {
+ if ( ! defined( 'WP_SESSION_COOKIE' ) ) {
+ define( 'WP_SESSION_COOKIE', '_awpcp_wp_session' );
+ }
+
+ if ( ! class_exists( 'Recursive_ArrayAccess' ) ) {
+ require_once AWPCP_DIR . '/vendors/wp-session/class-recursive-arrayaccess.php';
+ }
+
+ if ( ! class_exists( 'WP_Session_Utils' ) ) {
+ require_once AWPCP_DIR . '/vendors/wp-session/class-wp-session-utils.php';
+ }
+
+ if ( ! class_exists( 'WP_Session' ) ) {
+ require_once AWPCP_DIR . '/vendors/wp-session/class-wp-session.php';
+ }
+
+ add_filter( 'wp_session_expiration_variant', array( $this, 'set_expiration_variant_time' ), 99999 );
+ add_filter( 'wp_session_expiration', array( $this, 'set_expiration_time' ), 99999 );
+
+ return new AWPCP_Session( new AWPCP_WP_Session_Backend( WP_Session::get_instance() ) );
+
+ add_action( 'wp', array( $this, 'register_garbage_collection' ) );
+ add_action( 'wp_session_garbage_collection', array( $this, 'cleanup_session_data' ) );
+ }
+
+ /**
+ * Force the cookie expiration variant time to 23 hours
+ *
+ * @param int $exp Default expiration (1 hour)
+ * @return int
+ */
+ public function set_expiration_variant_time( $exp ) {
+ return ( 30 * 60 * 23 );
+ }
+
+ /**
+ * Force the cookie expiration time to 24 hours
+ *
+ * @param int $exp Default expiration (1 hour)
+ * @return int
+ */
+ public function set_expiration_time( $exp ) {
+ return ( 30 * 60 * 24 );
+ }
+
+ public function register_garbage_collection() {
+ if ( ! wp_next_scheduled( 'wp_session_garbage_collection' ) ) {
+ wp_schedule_event( time(), 'hourly', 'wp_session_garbage_collection' );
+ }
+ }
+
+ public function cleanup_session_data() {
+ if ( defined( 'WP_SETUP_CONFIG' ) ) {
+ return;
+ }
+
+ if ( defined( 'WP_INSTALLING' ) ) {
+ return;
+ }
+
+ $batch_size = 1000;
+
+ WP_Session_Utils::delete_old_sessions( $batch_size );
+ }
+
+ public function commit_session() {
+ return $this->session->commit();
+ }
+
+ public function get_session() {
+ return $this->session;
+ }
+}
diff --git a/another-wordpress-classifieds-plugin/includes/sessions/class-session.php b/another-wordpress-classifieds-plugin/includes/sessions/class-session.php
new file mode 100644
index 0000000..05016a3
--- /dev/null
+++ b/another-wordpress-classifieds-plugin/includes/sessions/class-session.php
@@ -0,0 +1,119 @@
+<?php
+
+/**
+ * @since next-release
+ */
+class AWPCP_Session {
+
+ private $backend;
+
+ public function __construct( $backend ) {
+ $this->backend = $backend;
+ }
+
+ public function set( $key, $value ) {
+ $key = sanitize_key( $key );
+
+ if ( is_array( $value ) ) {
+ $stored_value = $this->backend->set( $key, serialize( $value ) );
+ } else {
+ $stored_value = $this->backend->set( $key, $value );
+ }
+
+ return $stored_value;
+ }
+
+ public function get( $key ) {
+ return maybe_unserialize( $this->backend->get( sanitize_key( $key ) ) );
+ }
+
+ public function commit() {
+ return $this->backend->commit();
+ }
+}
+
+/**
+ * @since next-release
+ */
+class AWPCP_PHP_Session_Backend {
+
+ private $prefix;
+
+ public function __construct( $prefix ) {
+ $this->prefix = $prefix;
+ }
+
+ public function set( $key, $value ) {
+ if ( ! isset( $_SESSION[ 'awpcp-' . $this->prefix ] ) || ! is_array( $_SESSION[ 'awpcp-' . $this->prefix ] ) ) {
+ $_SESSION[ 'awpcp-' . $this->prefix ] = array( $key => $value );
+ } else {
+ $_SESSION[ 'awpcp-' . $this->prefix ][ $key ] = $value;
+ }
+
+ return $_SESSION[ 'awpcp-' . $this->prefix ][ $key ];
+ }
+
+ public function get( $key ) {
+ if ( ! isset( $_SESSION[ 'awpcp-' . $this->prefix ] ) && ! is_array( $_SESSION[ 'awpcp-' . $this->prefix ] ) ) {
+ return false;
+ }
+
+ if ( ! isset( $_SESSION[ 'awpcp-' . $this->prefix ][ $key ] ) ) {
+ return false;
+ }
+
+ return $_SESSION[ 'awpcp-' . $this->prefix ][ $key ];
+ }
+
+ public function commit() {}
+}
+
+/**
+ * @since next-release
+ */
+class AWPCP_WP_Session_Backend {
+
+ private $session;
+
+ /**
+ * @param $intance An instance of WP_Session.
+ */
+ public function __construct( $session ) {
+ $this->session = $session;
+ }
+
+ public function set( $key, $value ) {
+ return $this->session[ $key ] = $value;
+ }
+
+ public function get( $key ) {
+ return isset( $this->session[ $key ] ) ? $this->session[ $key ] : false;
+ }
+
+ public function commit() {
+ $this->session->write_data();
+ }
+}
+
+class AWPCP_Session_ {
+
+ /**
+ * Set a cookie to identify whether the cart is empty or not
+ *
+ * This is for hosts and caching plugins to identify if caching should be disabled
+ *
+ * @access public
+ * @since 1.8
+ * @param string $set Whether to set or destroy
+ * @return void
+ */
+ public function set_cart_cookie( $set = true ) {
+ if( ! headers_sent() ) {
+ if( $set ) {
+ @setcookie( 'edd_items_in_cart', '1', time() + 30 * 60, COOKIEPATH, COOKIE_DOMAIN, false );
+ } else {
+ @setcookie( 'edd_items_in_cart', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN, false );
+ }
+ }
+ }
+}
diff --git a/another-wordpress-classifieds-plugin/includes/settings/class-general-settings.php b/another-wordpress-classifieds-plugin/includes/settings/class-general-settings.php
index 2a1ebbe..3852063 100644
--- a/another-wordpress-classifieds-plugin/includes/settings/class-general-settings.php
+++ b/another-wordpress-classifieds-plugin/includes/settings/class-general-settings.php
@@ -37,6 +37,15 @@ class AWPCP_GeneralSettings {
$settings->add_setting( $key, 'awpcpadminaccesslevel', __( 'Who can access AWPCP Admin Dashboard', 'AWPCP' ), 'radio', 'admin', __( 'Role of WordPress users who can have admin access to Classifieds.', 'AWPCP' ), array( 'options' => $options ) );
$settings->add_setting( $key, 'awpcppagefilterswitch', __( 'Enable page filter', 'AWPCP' ), 'checkbox', 1, __( 'Uncheck this if you need to turn off the AWPCP page filter that prevents AWPCP classifieds children pages from showing up in your wp pages menu (You might need to do this if for example the AWPCP page filter is messing up your page menu. It means you will have to manually exclude the AWPCP children pages from showing in your page list. Some of the pages really should not be visible to your users by default).', 'AWPCP') );
+ $settings->add_setting(
+ $key,
+ 'use-php-sessions',
+ __( 'Use PHP Sessions', 'AWPCP' ),
+ 'checkbox',
+ false,
+ __( 'If checked, session data, such as current active region or other transient information we use to deliver a personalized experience, will be stored using PHP Sessions. When this setting is off (recommended), that information is temporarily stored in the database and retrieved using a cookie that identifies each visitor. The problem with cookies, however, is that sometimes they are not available; some cache techniques provided by plugins or hosting services disable cookies for not logged in users, for example.' )
+ );
+
// Section: General - Date & Time Format
$label = _x( 'Date & Time Format', 'settings', 'AWPCP' );
diff --git a/another-wordpress-classifieds-plugin/vendors/wp-session/class-recursive-arrayaccess.php b/another-wordpress-classifieds-plugin/vendors/wp-session/class-recursive-arrayaccess.php
new file mode 100644
index 0000000..be6294e
--- /dev/null
+++ b/another-wordpress-classifieds-plugin/vendors/wp-session/class-recursive-arrayaccess.php
@@ -0,0 +1,213 @@
+<?php
+/**
+ * Multidimensional ArrayAccess
+ *
+ * Allows ArrayAccess-like functionality with multidimensional arrays. Fully supports
+ * both sets and unsets.
+ *
+ * @package WordPress
+ * @subpackage Session
+ * @since 3.7.0
+ */
+
+/**
+ * Recursive array class to allow multidimensional array access.
+ *
+ * @package WordPress
+ * @since 3.7.0
+ */
+class Recursive_ArrayAccess implements ArrayAccess, Iterator, Countable {
+ /**
+ * Internal data collection.
+ *
+ * @var array
+ */
+ protected $container = array();
+
+ /**
+ * Flag whether or not the internal collection has been changed.
+ *
+ * @var bool
+ */
+ protected $dirty = false;
+
+ /**
+ * Default object constructor.
+ *
+ * @param array $data
+ */
+ protected function __construct( $data = array() ) {
+ foreach ( $data as $key => $value ) {
+ $this[ $key ] = $value;
+ }
+ }
+
+ /**
+ * Allow deep copies of objects
+ */
+ public function __clone() {
+ foreach ( $this->container as $key => $value ) {
+ if ( $value instanceof self ) {
+ $this[ $key ] = clone $value;
+ }
+ }
+ }
+
+ /**
+ * Output the data container as a multidimensional array.
+ *
+ * @return array
+ */
+ public function toArray() {
+ $data = $this->container;
+ foreach ( $data as $key => $value ) {
+ if ( $value instanceof self ) {
+ $data[ $key ] = $value->toArray();
+ }
+ }
+ return $data;
+ }
+
+ /*****************************************************************/
+ /* ArrayAccess Implementation */
+ /*****************************************************************/
+
+ /**
+ * Whether a offset exists
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ *
+ * @param mixed $offset An offset to check for.
+ *
+ * @return boolean true on success or false on failure.
+ */
+ public function offsetExists( $offset ) {
+ return isset( $this->container[ $offset ]) ;
+ }
+
+ /**
+ * Offset to retrieve
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ *
+ * @param mixed $offset The offset to retrieve.
+ *
+ * @return mixed Can return all value types.
+ */
+ public function offsetGet( $offset ) {
+ return isset( $this->container[ $offset ] ) ? $this->container[ $offset ] : null;
+ }
+
+ /**
+ * Offset to set
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ *
+ * @param mixed $offset The offset to assign the value to.
+ * @param mixed $value The value to set.
+ *
+ * @return void
+ */
+ public function offsetSet( $offset, $data ) {
+ if ( is_array( $data ) ) {
+ $data = new self( $data );
+ }
+ if ( $offset === null ) { // don't forget this!
+ $this->container[] = $data;
+ } else {
+ $this->container[ $offset ] = $data;
+ }
+
+ $this->dirty = true;
+ }
+
+ /**
+ * Offset to unset
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ *
+ * @param mixed $offset The offset to unset.
+ *
+ * @return void
+ */
+ public function offsetUnset( $offset ) {
+ unset( $this->container[ $offset ] );
+
+ $this->dirty = true;
+ }
+
+
+ /*****************************************************************/
+ /* Iterator Implementation */
+ /*****************************************************************/
+
+ /**
+ * Current position of the array.
+ *
+ * @link http://php.net/manual/en/iterator.current.php
+ *
+ * @return mixed
+ */
+ public function current() {
+ return current( $this->container );
+ }
+
+ /**
+ * Key of the current element.
+ *
+ * @link http://php.net/manual/en/iterator.key.php
+ *
+ * @return mixed
+ */
+ public function key() {
+ return key( $this->container );
+ }
+
+ /**
+ * Move the internal point of the container array to the next item
+ *
+ * @link http://php.net/manual/en/iterator.next.php
+ *
+ * @return void
+ */
+ public function next() {
+ next( $this->container );
+ }
+
+ /**
+ * Rewind the internal point of the container array.
+ *
+ * @link http://php.net/manual/en/iterator.rewind.php
+ *
+ * @return void
+ */
+ public function rewind() {
+ reset( $this->container );
+ }
+
+ /**
+ * Is the current key valid?
+ *
+ * @link http://php.net/manual/en/iterator.rewind.php
+ *
+ * @return bool
+ */
+ public function valid() {
+ return $this->offsetExists( $this->key() );
+ }
+
+ /*****************************************************************/
+ /* Countable Implementation */
+ /*****************************************************************/
+
+ /**
+ * Get the count of elements in the container array.
+ *
+ * @link http://php.net/manual/en/countable.count.php
+ *
+ * @return int
+ */
+ public function count() {
+ return count( $this->container );
+ }
+}
diff --git a/another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session-utils.php b/another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session-utils.php
new file mode 100644
index 0000000..ffd3c32
--- /dev/null
+++ b/another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session-utils.php
@@ -0,0 +1,135 @@
+<?php
+
+/**
+ * Utility class for sesion utilities
+ *
+ * THIS CLASS SHOULD NEVER BE INSTANTIATED
+ */
+class WP_Session_Utils {
+ /**
+ * Count the total sessions in the database.
+ *
+ * @global wpdb $wpdb
+ *
+ * @return int
+ */
+ public static function count_sessions() {
+ global $wpdb;
+
+ $query = "SELECT COUNT(*) FROM $wpdb->options WHERE option_name LIKE '_wp_session_expires_%'";
+
+ /**
+ * Filter the query in case tables are non-standard.
+ *
+ * @param string $query Database count query
+ */
+ $query = apply_filters( 'wp_session_count_query', $query );
+
+ $sessions = $wpdb->get_var( $query );
+
+ return absint( $sessions );
+ }
+
+ /**
+ * Create a new, random session in the database.
+ *
+ * @param null|string $date
+ */
+ public static function create_dummy_session( $date = null ) {
+ // Generate our date
+ if ( null !== $date ) {
+ $time = strtotime( $date );
+
+ if ( false === $time ) {
+ $date = null;
+ } else {
+ $expires = date( 'U', strtotime( $date ) );
+ }
+ }
+
+ // If null was passed, or if the string parsing failed, fall back on a default
+ if ( null === $date ) {
+ /**
+ * Filter the expiration of the session in the database
+ *
+ * @param int
+ */
+ $expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 );
+ }
+
+ $session_id = self::generate_id();
+
+ // Store the session
+ add_option( "_wp_session_{$session_id}", array(), '', 'no' );
+ add_option( "_wp_session_expires_{$session_id}", $expires, '', 'no' );
+ }
+
+ /**
+ * Delete old sessions from the database.
+ *
+ * @param int $limit Maximum number of sessions to delete.
+ *
+ * @global wpdb $wpdb
+ *
+ * @return int Sessions deleted.
+ */
+ public static function delete_old_sessions( $limit = 1000 ) {
+ global $wpdb;
+
+ $limit = absint( $limit );
+ $keys = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_wp_session_expires_%' ORDER BY option_value ASC LIMIT 0, {$limit}" );
+
+ $now = time();
+ $expired = array();
+ $count = 0;
+
+ foreach( $keys as $expiration ) {
+ $key = $expiration->option_name;
+ $expires = $expiration->option_value;
+
+ if ( $now > $expires ) {
+ $session_id = addslashes( substr( $key, 20 ) );
+
+ $expired[] = $key;
+ $expired[] = "_wp_session_{$session_id}";
+
+ $count += 1;
+ }
+ }
+
+ // Delete expired sessions
+ if ( ! empty( $expired ) ) {
+ $names = implode( "','", $expired );
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name IN ('{$names}')" );
+ }
+
+ return $count;
+ }
+
+ /**
+ * Remove all sessions from the database, regardless of expiration.
+ *
+ * @global wpdb $wpdb
+ *
+ * @return int Sessions deleted
+ */
+ public static function delete_all_sessions() {
+ global $wpdb;
+
+ $count = $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_wp_session_%'" );
+
+ return (int) ( $count / 2 );
+ }
+
+ /**
+ * Generate a new, random session ID.
+ *
+ * @return string
+ */
+ public static function generate_id() {
+ require_once( ABSPATH . 'wp-includes/class-phpass.php' );
+ $hash = new PasswordHash( 8, false );
+
+ return md5( $hash->get_random_bytes( 32 ) );
+ }
+}
\ No newline at end of file
diff --git a/another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session.php b/another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session.php
new file mode 100644
index 0000000..cc58a5e
--- /dev/null
+++ b/another-wordpress-classifieds-plugin/vendors/wp-session/class-wp-session.php
@@ -0,0 +1,225 @@
+<?php
+/**
+ * WordPress session managment.
+ *
+ * Standardizes WordPress session data using database-backed options for storage.
+ * for storing user session information.
+ *
+ * @package WordPress
+ * @subpackage Session
+ * @since 3.7.0
+ */
+
+/**
+ * WordPress Session class for managing user session data.
+ *
+ * @package WordPress
+ * @since 3.7.0
+ */
+final class WP_Session extends Recursive_ArrayAccess {
+ /**
+ * ID of the current session.
+ *
+ * @var string
+ */
+ protected $session_id;
+
+ /**
+ * Unix timestamp when session expires.
+ *
+ * @var int
+ */
+ protected $expires;
+
+ /**
+ * Unix timestamp indicating when the expiration time needs to be reset.
+ *
+ * @var int
+ */
+ protected $exp_variant;
+
+ /**
+ * Singleton instance.
+ *
+ * @var bool|WP_Session
+ */
+ private static $instance = false;
+
+ /**
+ * Retrieve the current session instance.
+ *
+ * @param bool $session_id Session ID from which to populate data.
+ *
+ * @return bool|WP_Session
+ */
+ public static function get_instance() {
+ if ( ! self::$instance ) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Default constructor.
+ * Will rebuild the session collection from the given session ID if it exists. Otherwise, will
+ * create a new session with that ID.
+ *
+ * @param $session_id
+ * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
+ */
+ protected function __construct() {
+ if ( isset( $_COOKIE[WP_SESSION_COOKIE] ) ) {
+ $cookie = stripslashes( $_COOKIE[WP_SESSION_COOKIE] );
+ $cookie_crumbs = explode( '||', $cookie );
+
+ $this->session_id = $cookie_crumbs[0];
+ $this->expires = $cookie_crumbs[1];
+ $this->exp_variant = $cookie_crumbs[2];
+
+ // Update the session expiration if we're past the variant time
+ if ( time() > $this->exp_variant ) {
+ $this->set_expiration();
+ delete_option( "_wp_session_expires_{$this->session_id}" );
+ add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
+ }
+ } else {
+ $this->session_id = WP_Session_Utils::generate_id();
+ $this->set_expiration();
+ }
+
+ $this->read_data();
+
+ $this->set_cookie();
+
+ }
+
+ /**
+ * Set both the expiration time and the expiration variant.
+ *
+ * If the current time is below the variant, we don't update the session's expiration time. If it's
+ * greater than the variant, then we update the expiration time in the database. This prevents
+ * writing to the database on every page load for active sessions and only updates the expiration
+ * time if we're nearing when the session actually expires.
+ *
+ * By default, the expiration time is set to 30 minutes.
+ * By default, the expiration variant is set to 24 minutes.
+ *
+ * As a result, the session expiration time - at a maximum - will only be written to the database once
+ * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by
+ * the browser, and the old session will be queued for deletion by the garbage collector.
+ *
+ * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data.
+ * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions.
+ */
+ protected function set_expiration() {
+ $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 );
+ $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 );
+ }
+
+ /**
+ * Set the session cookie
+ * @uses apply_filters Calls `wp_session_cookie_secure` to set the $secure parameter of setcookie()
+ * @uses apply_filters Calls `wp_session_cookie_httponly` to set the $httponly parameter of setcookie()
+ */
+ protected function set_cookie() {
+ $secure = apply_filters('wp_session_cookie_secure', false);
+ $httponly = apply_filters('wp_session_cookie_httponly', false);
+ setcookie( WP_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN, $secure, $httponly );
+ }
+
+ /**
+ * Read data from a transient for the current session.
+ *
+ * Automatically resets the expiration time for the session transient to some time in the future.
+ *
+ * @return array
+ */
+ protected function read_data() {
+ $this->container = get_option( "_wp_session_{$this->session_id}", array() );
+
+ return $this->container;
+ }
+
+ /**
+ * Write the data from the current session to the data storage system.
+ */
+ public function write_data() {
+ $option_key = "_wp_session_{$this->session_id}";
+
+ if ( false === get_option( $option_key ) ) {
+ add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
+ add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
+ } else {
+ delete_option( "_wp_session_{$this->session_id}" );
+ add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
+ }
+ }
+
+ /**
+ * Output the current container contents as a JSON-encoded string.
+ *
+ * @return string
+ */
+ public function json_out() {
+ return json_encode( $this->container );
+ }
+
+ /**
+ * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents.
+ *
+ * @param string $data
+ *
+ * @return bool
+ */
+ public function json_in( $data ) {
+ $array = json_decode( $data );
+
+ if ( is_array( $array ) ) {
+ $this->container = $array;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Regenerate the current session's ID.
+ *
+ * @param bool $delete_old Flag whether or not to delete the old session data from the server.
+ */
+ public function regenerate_id( $delete_old = false ) {
+ if ( $delete_old ) {
+ delete_option( "_wp_session_{$this->session_id}" );
+ }
+
+ $this->session_id = WP_Session_Utils::generate_id();
+
+ $this->set_cookie();
+ }
+
+ /**
+ * Check if a session has been initialized.
+ *
+ * @return bool
+ */
+ public function session_started() {
+ return !!self::$instance;
+ }
+
+ /**
+ * Return the read-only cache expiration value.
+ *
+ * @return int
+ */
+ public function cache_expiration() {
+ return $this->expires;
+ }
+
+ /**
+ * Flushes all session variables.
+ */
+ public function reset() {
+ $this->container = array();
+ }
+}
diff --git a/premium-modules/awpcp-region-control/includes/class-location-service.php b/premium-modules/awpcp-region-control/includes/class-location-service.php
index 65c14be..36579a7 100644
--- a/premium-modules/awpcp-region-control/includes/class-location-service.php
+++ b/premium-modules/awpcp-region-control/includes/class-location-service.php
@@ -1,18 +1,18 @@
<?php
function awpcp_location_service() {
- return new AWPCP_LocationService( awpcp_regions_api(), awpcp_cookie_manager(), awpcp_request() );
+ return new AWPCP_LocationService( awpcp_regions_api(), awpcp_session(), awpcp_request() );
}
class AWPCP_LocationService {
private $regions;
- private $cookies;
+ private $session;
private $request;
- public function __construct( $regions, $cookies, $request ) {
+ public function __construct( $regions, $session, $request ) {
$this->regions = $regions;
- $this->cookies = $cookies;
+ $this->session = $session;
$this->request = $request;
}
@@ -78,13 +78,7 @@ class AWPCP_LocationService {
private function save_current_location( $current_location ) {
$this->remove_current_location_from_session();
-
- $cookie_value = array_merge(
- array( 'timestamp' => current_time( 'timestamp' ) ),
- $this->normalize_location_array( $current_location )
- );
-
- $this->cookies->set_cookie( 'awpcp-regions-current-location', $cookie_value );
+ $this->session->set( 'current-location', $this->normalize_location_array( $current_location ) );
}
private function remove_current_location_from_session() {
@@ -106,21 +100,21 @@ class AWPCP_LocationService {
}
public function get_current_location_from_request() {
- $current_location = $this->get_current_location_from_cookie();
+ $current_location = $this->get_current_location_from_plugin_session();
if ( ! empty( $current_location ) ) {
return $current_location;
}
- return $this->get_current_location_from_session();
+ return $this->get_current_location_from_php_session();
}
- private function get_current_location_from_cookie() {
- $current_location = $this->cookies->get_cookie( 'awpcp-regions-current-location' );
+ private function get_current_location_from_plugin_session() {
+ $current_location = $this->session->get( 'current-location' );
return array_filter( (array) $current_location );
}
- private function get_current_location_from_session() {
+ private function get_current_location_from_php_session() {
$current_location = $this->normalize_location_array( $_SESSION );
return array_filter( $current_location );
}
--
2.2.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment