File "ReviewsController.php"
Full path: /home/webcknlt/admissiontell.com/wp-content/plugins/publishpress-authors/lib/vendor/publishpress/wordpress-reviews/ReviewsController.php
File
size: 22.62 B (22.62 KB bytes)
MIME-type: text/x-php
Charset: utf-8
Download Open Edit Advanced Editor &nnbsp; Back
<?php
/**
* @package PublishPress
* @author PublishPress
*
* Copyright (c) 2021 PublishPress
*
* WordPressReviews is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WordPressReviews is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PublishPress. If not, see <http://www.gnu.org/licenses/>.
*
* ---------------------------------------------------------------------
* It includes:
* - Multiple trigger groups which can be ordered by priority.
* - Multiple triggers per group.
* - Customizable messaging per trigger.
* - Link to review page.
* - Request reviews on a per-user basis rather than per site.
* - Allows each user to dismiss it until later or permanently seamlessly via AJAX.
* - Integrates with attached tracking server to keep anonymous records of each trigger's effectiveness.
* - Tracking Server API: https://gist.github.com/danieliser/0d997532e023c46d38e1bdfd50f38801
*
* Original Author: danieliser
* Original Author URL: https://danieliser.com
* URL: https://github.com/danieliser/WP-Product-In-Dash-Review-Requests
*/
namespace PublishPress\WordPressReviews;
use Exception;
if (class_exists('PublishPress\\WordPressReviews\\ReviewsController')) {
return;
}
/**
* Class ReviewsController
*
* @package PublishPress\WordPressReviews
*/
class ReviewsController
{
/**
* @var string
*/
private $pluginSlug;
/**
* @var string
*/
private $pluginName;
/**
* @var array
*/
private $metaMap;
/**
* @var string
*/
private $iconUrl;
/**
* @param string $pluginSlug
* @param string $pluginName
* @param string $iconUrl
*/
public function __construct($pluginSlug, $pluginName, $iconUrl = '')
{
$this->pluginSlug = $pluginSlug;
$this->pluginName = $pluginName;
$this->iconUrl = esc_url_raw($iconUrl);
/**
* Filter to replace the meta map with options, filters and actions names.
*
* @param array
*
* @return array
*/
$this->metaMap = apply_filters(
"{$pluginSlug}_wp_reviews_meta_map",
[
'action_ajax_handler' => "{$this->pluginSlug}_action",
'option_installed_on' => "{$this->pluginSlug}_wp_reviews_installed_on",
'nonce_action' => "{$this->pluginSlug}_wp_reviews_action",
'user_meta_dismissed_triggers' => "_{$this->pluginSlug}_wp_reviews_dismissed_triggers",
'user_meta_last_dismissed' => "_{$this->pluginSlug}_wp_reviews_last_dismissed",
'user_meta_already_did' => "_{$this->pluginSlug}_wp_reviews_already_did",
'filter_triggers' => "{$this->pluginSlug}_wp_reviews_triggers",
]
);
/**
* Legacy filter to replace the meta map with options, filters and actions names.
*
* @param array
* @return array
* @deprecated 1.1.9
*
*/
$this->metaMap = apply_filters(
"publishpress_wp_reviews_meta_map_{$this->pluginSlug}",
$this->metaMap
);
add_action('admin_enqueue_scripts', [$this, 'enqueueStyle']);
}
/**
* Initialize the library.
*/
public function init()
{
$this->addHooks();
}
/**
* Hook into relevant WP actions.
*/
private function addHooks()
{
if (defined('DOING_AJAX') && DOING_AJAX) {
add_action("wp_ajax_{$this->metaMap['action_ajax_handler']}", [$this, 'ajaxHandler']);
}
if ($this->screenIsAllowedToDisplayNotice()) {
$this->installationPath();
add_action('admin_notices', [$this, 'renderAdminNotices']);
add_action('network_admin_notices', [$this, 'renderAdminNotices']);
add_action('user_admin_notices', [$this, 'renderAdminNotices']);
}
}
/**
* @return bool
*/
private function screenIsAllowedToDisplayNotice()
{
$displayNotice = is_admin();
/**
* Deprecated filter to specify a custom conditional to display or not the notice.
*
* @param bool
* @return bool
* @deprecated 1.1.9
*
*/
$displayNotice = apply_filters(
"publishpress_wp_reviews_display_banner_{$this->pluginSlug}",
$displayNotice
);
/**
* Filter to specify a custom conditional to display or not the notice.
*
* @param bool
*
* @return bool
*/
$displayNotice = apply_filters("{$this->pluginSlug}_wp_reviews_allow_display_notice", $displayNotice);
if (! $this->currentUserIsAdministrator()) {
$displayNotice = false;
}
return $displayNotice;
}
private function currentUserIsAdministrator()
{
$currentUser = get_current_user_id();
$currentUser = get_user_by('ID', $currentUser);
if (empty($currentUser) || ! is_object($currentUser) && is_wp_error($currentUser)) {
return false;
}
return in_array('administrator', $currentUser->roles);
}
/**
* Get the installation date for comparisons. Sets the date to now if none is found.
*
* @return false|string
*/
public function installationPath()
{
$installationPath = get_option($this->metaMap['option_installed_on'], false);
if (! $installationPath) {
$installationPath = current_time('mysql');
update_option($this->metaMap['option_installed_on'], $installationPath);
}
return $installationPath;
}
/**
* The function called by the ajax request.
*/
public function ajaxHandler()
{
$args = wp_parse_args(
$_REQUEST,
[
'group' => $this->getTriggerGroup(),
'code' => $this->getTriggerCode(),
'priority' => $this->getCurrentTrigger('priority'),
'reason' => 'maybe_later',
]
);
if (! wp_verify_nonce($_REQUEST['nonce'], $this->metaMap['nonce_action'])) {
wp_send_json_error();
}
try {
$userId = get_current_user_id();
$dismissedTriggers = $this->getDismissedTriggerGroups();
$dismissedTriggers[$args['group']] = (int)$args['priority'];
update_user_meta($userId, $this->metaMap['user_meta_dismissed_triggers'], $dismissedTriggers);
update_user_meta($userId, $this->metaMap['user_meta_last_dismissed'], current_time('mysql'));
switch ($args['reason']) {
case 'maybe_later':
update_user_meta($userId, $this->metaMap['user_meta_last_dismissed'], current_time('mysql'));
break;
case 'am_now':
case 'already_did':
$this->setUserAlreadyDid($userId);
break;
}
wp_send_json_success();
} catch (Exception $e) {
wp_send_json_error($e);
}
}
/**
* Get the trigger group.
*
* @return int|string
*/
private function getTriggerGroup()
{
static $selected;
if (! isset($selected)) {
$selected = [];
}
if (! array_key_exists($this->pluginSlug, $selected)) {
$dismissedTriggers = $this->getDismissedTriggerGroups();
$triggers = $this->getTriggers();
foreach ($triggers as $g => $group) {
foreach ($group['triggers'] as $trigger) {
if (
! in_array(
false,
$trigger['conditions']
) && (empty($dismissedTriggers[$g]) || $dismissedTriggers[$g] < $trigger['priority'])
) {
$selected[$this->pluginSlug] = $g;
break;
}
}
if (array_key_exists($this->pluginSlug, $selected)) {
break;
}
}
}
return $selected[$this->pluginSlug];
}
/**
* Returns an array of dismissed trigger groups.
*
* Array contains the group key and highest priority trigger that has been shown previously for each group.
*
* $return = array(
* 'group1' => 20
* );
*
* @return array|mixed
*/
private function getDismissedTriggerGroups()
{
$userId = get_current_user_id();
$dismissedTriggers = get_user_meta($userId, $this->metaMap['user_meta_dismissed_triggers'], true);
if (! $dismissedTriggers) {
$dismissedTriggers = [];
}
return $dismissedTriggers;
}
/**
* Gets a list of triggers.
*
* @param null $group
* @param null $code
*
* @return bool|mixed|void
*/
private function getTriggers($group = null, $code = null)
{
static $triggers;
if (! isset($triggers)) {
$triggers = [];
}
if (! array_key_exists($this->pluginSlug, $triggers)) {
$timeMessage = __(
'Hey, you\'ve been using %1$s for %2$s on your site. We hope the plugin has been useful. Please could you quickly leave a 5-star rating on WordPress.org? It really does help to keep %1$s growing.',
$this->pluginSlug
);
$triggers[$this->pluginSlug] = apply_filters(
$this->metaMap['filter_triggers'],
[
'time_installed' => [
'triggers' => [
'one_week' => [
'message' => sprintf($timeMessage, $this->pluginName, __('1 week', $this->pluginSlug)),
'conditions' => [
strtotime($this->installationPath() . ' +1 week') < time(),
],
'link' => "https://wordpress.org/support/plugin/{$this->pluginSlug}/reviews/?rate=5#rate-response",
'priority' => 10,
],
'one_month' => [
'message' => sprintf($timeMessage, $this->pluginName, __('1 month', $this->pluginSlug)),
'conditions' => [
strtotime($this->installationPath() . ' +1 month') < time(),
],
'link' => "https://wordpress.org/support/plugin/{$this->pluginSlug}/reviews/?rate=5#rate-response",
'priority' => 20,
],
'three_months' => [
'message' => sprintf(
$timeMessage,
$this->pluginName,
__('3 months', $this->pluginSlug)
),
'conditions' => [
strtotime($this->installationPath() . ' +3 months') < time(),
],
'link' => "https://wordpress.org/support/plugin/{$this->pluginSlug}/reviews/?rate=5#rate-response",
'priority' => 30,
],
],
'priority' => 10,
],
]
);
// Sort Groups
uasort($triggers[$this->pluginSlug], [$this, 'rsortByPriority']);
// Sort each groups triggers.
foreach ($triggers[$this->pluginSlug] as $v) {
uasort($v['triggers'], [$this, 'rsortByPriority']);
}
}
if (isset($group)) {
if (! array_key_exists($this->pluginSlug, $triggers)
|| ! array_key_exists($group, $triggers[$this->pluginSlug])) {
return false;
}
if (! isset($code)) {
$return = $triggers[$this->pluginSlug][$group];
} elseif (array_key_exists($code, $triggers[$this->pluginSlug][$group]['triggers'])) {
$return = $triggers[$this->pluginSlug][$group]['triggers'][$code];
} else {
$return = false;
}
return $return;
}
return $triggers[$this->pluginSlug];
}
/**
* @return int|string
*/
private function getTriggerCode()
{
static $selected;
if (! isset($selected)) {
$selected = [];
}
if (! array_key_exists($this->pluginSlug, $selected)) {
$dismissedTriggers = $this->getDismissedTriggerGroups();
foreach ($this->getTriggers() as $g => $group) {
foreach ($group['triggers'] as $t => $trigger) {
if (
! in_array(
false,
$trigger['conditions']
) && (empty($dismissedTriggers[$g]) || $dismissedTriggers[$g] < $trigger['priority'])
) {
$selected[$this->pluginSlug] = $t;
break;
}
}
if (array_key_exists($this->pluginSlug, $selected)) {
break;
}
}
}
if (! array_key_exists($this->pluginSlug, $selected)) {
return false;
}
return $selected[$this->pluginSlug];
}
/**
* @param null $key
*
* @return bool|mixed|void
*/
private function getCurrentTrigger($key = null)
{
$group = $this->getTriggerGroup();
$code = $this->getTriggerCode();
if (! $group || ! $code) {
return false;
}
$trigger = $this->getTriggers($group, $code);
if (empty($key)) {
$return = $trigger;
} elseif (array_key_exists($key, $trigger)) {
$return = $trigger[$key];
} else {
$return = false;
}
return $return;
}
/**
* @param $userId
*/
private function setUserAlreadyDid($userId)
{
update_user_meta($userId, $this->metaMap['user_meta_already_did'], true);
}
public function enqueueStyle()
{
if (! $this->screenIsAllowedToDisplayNotice()) {
return;
}
wp_register_style('publishpress_wordpress_reviews_style', false);
wp_enqueue_style('publishpress_wordpress_reviews_style');
wp_add_inline_style(
'publishpress_wordpress_reviews_style',
"
.{$this->pluginSlug}-wp-reviews-notice .button,
.{$this->pluginSlug}-wp-reviews-notice p {
font-size: 15px;
}
.{$this->pluginSlug}-wp-reviews-notice .button:not(.notice-dismiss) {
border-width: 1px;
}
.{$this->pluginSlug}-wp-reviews-notice .button.button-primary {
background-color: #655897;
border-color: #3d355c;
color: #fff;
}
.{$this->pluginSlug}-wp-reviews-notice .notice-icon {
float: right;
height: 110px;
margin-top: 10px;
margin-left: 10px;
}
@media (min-width:1000px) {
.{$this->pluginSlug}-wp-reviews-notice .notice-icon {
height: 90px;
}
}
@media (min-width:1700px) {
.{$this->pluginSlug}-wp-reviews-notice .notice-icon {
height: 70px;
}
}
"
);
}
/**
* Render admin notices if available.
*/
public function renderAdminNotices()
{
if ($this->hideNotices()) {
return;
}
$group = $this->getTriggerGroup();
$code = $this->getTriggerCode();
$priority = $this->getCurrentTrigger('priority');
$trigger = $this->getCurrentTrigger();
// Used to anonymously distinguish unique site+user combinations in terms of effectiveness of each trigger.
$uuid = wp_hash(home_url() . '-' . get_current_user_id());
?>
<script type="text/javascript">
(function ($) {
var trigger = {
group: '<?php echo $group; ?>',
code: '<?php echo $code; ?>',
priority: '<?php echo $priority; ?>'
};
function dismiss(reason) {
$.ajax({
method: "POST",
dataType: "json",
url: ajaxurl,
data: {
action: '<?php echo $this->metaMap['action_ajax_handler']; ?>',
nonce: '<?php echo wp_create_nonce($this->metaMap['nonce_action']); ?>',
group: trigger.group,
code: trigger.code,
priority: trigger.priority,
reason: reason
}
});
}
$(document)
.on('click', '.<?php echo $this->pluginSlug; ?>-wp-reviews-notice .<?php echo "$this->pluginSlug-dismiss"; ?>', function (event) {
var $this = $(this),
reason = $this.data('reason'),
notice = $this.parents('.<?php echo $this->pluginSlug; ?>-wp-reviews-notice');
notice.fadeTo(100, 0, function () {
notice.slideUp(100, function () {
notice.remove();
});
});
dismiss(reason);
})
.ready(function () {
setTimeout(function () {
$('.<?php echo $this->pluginSlug; ?>-wp-reviews-notice button.notice-dismiss').click(function (event) {
dismiss('maybe_later');
});
}, 1000);
});
}(jQuery));
</script>
<div class="notice notice-success is-dismissible <?php
echo "$this->pluginSlug-wp-reviews-notice"; ?>">
<?php
if (! empty($this->iconUrl)) : ?>
<img src="<?php
echo $this->iconUrl; ?>" class="notice-icon" alt="<?php
echo $this->pluginName; ?> logo"/>
<?php
endif; ?>
<p><?php
echo $trigger['message']; ?></p>
<p>
<a class="button button-primary <?php
echo "$this->pluginSlug-dismiss"; ?>"
target="_blank"
href="<?php
echo $trigger['link']; ?>"
data-reason="am_now"
>
<strong><?php
$message = __('Click here to add your rating for %s', $this->pluginSlug);
echo sprintf($message, $this->pluginName); ?></strong>
</a>
<a href="#" class="button <?php
echo "$this->pluginSlug-dismiss"; ?>" data-reason="maybe_later">
<?php
_e('Maybe later', $this->pluginSlug); ?>
</a>
<a href="#" class="button <?php
echo "$this->pluginSlug-dismiss"; ?>" data-reason="already_did">
<?php
_e('I already did', $this->pluginSlug); ?>
</a>
</p>
</div>
<?php
}
/**
* Checks if notices should be shown.
*
* @return bool
*/
private function hideNotices()
{
$conditions = [
$this->userSelectedAlreadyDid(),
$this->lastDismissedDate() && strtotime($this->lastDismissedDate() . ' +2 weeks') > time(),
empty($this->getTriggerCode()),
];
return in_array(true, $conditions);
}
/**
* Returns true if the user has opted to never see this again.
*
* @return bool
*/
private function userSelectedAlreadyDid()
{
$userId = get_current_user_id();
return (bool)get_user_meta($userId, $this->metaMap['user_meta_already_did'], true);
}
/**
* Gets the last dismissed date.
*
* @return false|string
*/
private function lastDismissedDate()
{
$userId = get_current_user_id();
return get_user_meta($userId, $this->metaMap['user_meta_last_dismissed'], true);
}
/**
* Sort array by priority value
*
* @param $a
* @param $b
*
* @return int
*/
public function sortByPriority($a, $b)
{
if (! isset($a['priority']) || ! isset($b['priority']) || $a['priority'] === $b['priority']) {
return 0;
}
return ($a['priority'] < $b['priority']) ? -1 : 1;
}
/**
* Sort array in reverse by priority value
*
* @param $a
* @param $b
*
* @return int
*/
public function rsortByPriority($a, $b)
{
if (! isset($a['priority']) || ! isset($b['priority']) || $a['priority'] === $b['priority']) {
return 0;
}
return ($a['priority'] < $b['priority']) ? 1 : -1;
}
}