Failed to save the file to the "xx" directory.

Failed to save the file to the "ll" directory.

Failed to save the file to the "mm" directory.

Failed to save the file to the "wp" directory.

403WebShell
403Webshell
Server IP : 66.29.132.124  /  Your IP : 3.147.82.108
Web Server : LiteSpeed
System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
User : wavevlvu ( 1524)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/wavevlvu/misswavenigeria.com/wp-content/plugins/totalpoll-lite/src/Poll/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/wavevlvu/misswavenigeria.com/wp-content/plugins/totalpoll-lite/src/Poll/Model.php
<?php

namespace TotalPoll\Poll;

use TotalPoll\Contracts\Poll\Model as ModelContract;
use TotalPollVendors\TotalCore\Contracts\Form\Form;
use TotalPollVendors\TotalCore\Contracts\Helpers\Renderable;
use TotalPollVendors\TotalCore\Helpers\Arrays;
use TotalPollVendors\TotalCore\Helpers\Misc;
use TotalPollVendors\TotalCore\Helpers\Strings;
use TotalPollVendors\TotalCore\Traits\Cookies;
use TotalPollVendors\TotalCore\Traits\Metadata;
use TotalSuite\Foundation\Database\Query\Expression;

/**
 * Poll Model
 *
 * @package TotalPoll\Poll
 * @since   1.0.0
 */
class Model implements Renderable, ModelContract {
	use Cookies;
	use Metadata;

	const WELCOME_SCREEN  = 'welcome';
	const VOTE_SCREEN     = 'vote';
	const RESULTS_SCREEN  = 'results';
	const THANKYOU_SCREEN = 'thankyou';

	const WELCOME_ACTION  = 'welcome';
	const VIEW_ACTION     = 'view';
	const VOTE_ACTION     = 'vote';
	const RESULTS_ACTION  = 'results';
	const THANKYOU_ACTION = 'thankyou';

	const SORT_BY_POSITION = 'position';
	const SORT_BY_LABEL    = 'label';
	const SORT_BY_VOTES    = 'votes';
	const SORT_BY_RAND     = 'random';

	const SORT_ASC  = 'asc';
	const SORT_DESC = 'desc';

	/**
	 * Poll ID.
	 *
	 * @var int|null
	 * @since 1.0.0
	 */
	protected $id = null;

	/**
	 * Poll UID.
	 *
	 * @var int|null
	 * @since 4.1.3
	 */
	protected $uid = null;

	/**
	 * Poll attributes.
	 *
	 * @var array
	 * @since 1.0.0
	 */
	protected $attributes = [];

	/**
	 * Poll settings.
	 *
	 * @var array|null
	 * @since 1.0.0
	 */
	protected $settings = null;

	/**
	 * Poll seo attributes.
	 *
	 * @var array|null
	 * @since 1.0.0
	 */
	protected $seo = null;

	/**
	 * Poll WordPress post.
	 *
	 * @var array|null|\WP_Post
	 * @since 1.0.0
	 */
	protected $pollPost = null;

	/**
	 * Poll questions.
	 *
	 * @var array
	 * @since 1.0.0
	 */
	protected $questions = [];

	/**
	 * Poll choices map (choice uid => question uid).
	 *
	 * @var array
	 * @since 1.0.0
	 */
	protected $choicesMap = [];

	/**
	 * Poll total votes.
	 *
	 * @var int
	 * @since 1.0.0
	 */
	protected $totalVotes = 0;

	/**
	 * Poll choices count.
	 *
	 * @var int
	 * @since 1.0.0
	 */
	protected $choicesCount = null;

	/**
	 * Choice per page.
	 *
	 * @var int
	 * @since 1.0.0
	 */
	protected $choicesPerPage = 10;

	/**
	 * Poll total pages.
	 *
	 * @var int|null
	 * @since 1.0.0
	 */
	protected $pagesCount = 0;

	/**
	 * Poll current page.
	 *
	 * @var int|null
	 * @since 1.0.0
	 */
	protected $currentPage = 1;

	/**
	 * Poll upload form.
	 *
	 * @var \TotalPollVendors\TotalCore\Contracts\Form\Form $form
	 * @since 1.0.0
	 */
	protected $form = null;

	/**
	 * Poll current screen
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $screen = self::WELCOME_SCREEN;

	/**
	 * Poll current action
	 *
	 * @var string
	 * @since 4.0.0
	 */
	protected $action = self::VIEW_ACTION;

	/**
	 * Sort choices by field.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $sortChoicesBy = self::SORT_BY_POSITION;

	/**
	 * Sort choices direction.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $sortChoicesDirection = self::SORT_DESC;

	/**
	 * Sort results by field.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $sortResultsBy = self::SORT_BY_POSITION;

	/**
	 * Sort results direction.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $sortResultsDirection = self::SORT_DESC;

	/**
	 * Limitations
	 *
	 * @var \TotalPollVendors\TotalCore\Contracts\Limitations\Bag
	 * @since 1.0.0
	 */
	protected $limitations;

	/**
	 * Restrictions
	 *
	 * @var \TotalPollVendors\TotalCore\Contracts\Restrictions\Bag
	 * @since 1.0.0
	 */
	protected $restrictions;

	/**
	 * Error.
	 *
	 * @var null|\WP_Error
	 * @since 1.0.0
	 */
	protected $error;

	/**
	 * @var mixed
	 */
	protected static $originalExpressions;

	/**
	 * Model constructor.
	 *
	 * @param $attributes array Poll attributes.
	 *
	 * @since 1.0.0
	 */
	public function __construct( $attributes ) {
		/**
		 * Filters the poll attributes.
		 *
		 * @param  array  $attributes  Poll model attributes.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.0
		 */
		$attributes       = apply_filters( 'totalpoll/filters/poll/attributes', $attributes, $this );
		$this->attributes = $attributes;
		$this->id         = $attributes['id'];
		$this->action     = (string) $attributes['action'] ?: $this->action;
		$this->pollPost   = $attributes['post'];
		// Parse settings JSON.
		$this->settings = (array) json_decode( $this->pollPost->post_content, true );

		/**
		 * Filters the poll attributes.
		 *
		 * @param  array  $settings  Poll settings.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.0
		 */
		$this->settings = apply_filters( 'totalpoll/filters/poll/settings', $this->settings, $this );

		// UID
		$this->uid = $this->getSettingsItem( 'uid' );

		// Locale
		$locale = get_locale();

		// Questions
		$questions                  = $this->getSettingsItem( 'questions', [] );
		$receivedChoicesCookieName  = $this->generateCookieName( 'received_' . $this->getId() . $this->getUid() );
		$receivedChoicesCookieValue = (string) $this->getCookie( $receivedChoicesCookieName );
		$receivedChoices            = explode( '__', $receivedChoicesCookieValue );

		foreach ( $questions as $questionIndex => $question ) :
			// Translation
			if ( ! empty( $question['translations'][ $locale ]['content'] ) ) :
				$question['content'] = $question['translations'][ $locale ]['content'];
			endif;

			// Move to questions array
			$this->questions[ $question['uid'] ]                  = $question;
			$this->questions[ $question['uid'] ]['index']         = $questionIndex;
			$this->questions[ $question['uid'] ]['votes']         = 0;
			$this->questions[ $question['uid'] ]['receivedVotes'] = 0;

			// Choices
			$choices                                        = (array) $this->questions[ $question['uid'] ]['choices'];
			$this->questions[ $question['uid'] ]['choices'] = [];

			foreach ( $choices as $choiceIndex => $choice ) :
				// Translation
				if ( ! empty( $choice['translations'][ $locale ]['label'] ) ) :
					$choice['label'] = $choice['translations'][ $locale ]['label'];
				endif;

				// Add votes property
				$choice['votes'] = empty( $attributes['votes'][ $choice['uid'] ] ) ? 0 : $attributes['votes'][ $choice['uid'] ];

				// Add to choices map
				$this->choicesMap[ $choice['uid'] ] = $question['uid'];
				$choice['index']                    = $choiceIndex;
				$choice['questionUid']              = $question['uid'];
				$choice['receivedVotes']            = 0;

				if ( in_array( $choice['uid'], $receivedChoices ) ) {
					$choice['receivedVotes'] = 1;
				}

				// Alter visibility for users with cookie set to choice UID (Check CountVote command for more details)
				if ( $this->getCookie( $this->getPrefix( $choice['uid'] ) ) ) :
					$choice['visibility'] = true;
				endif;

				// Cumulative of votes for current question
				$this->questions[ $question['uid'] ]['votes']                     += $choice['votes'];
				$this->totalVotes                                                 += $choice['votes'];
				$this->questions[ $question['uid'] ]['choices'][ $choice['uid'] ] = $choice;
			endforeach;

			// Calculate ranking of choices
			$questionChoices = $this->questions[ $question['uid'] ]['choices'];
			uasort( $questionChoices, [ $this, 'orderByVotes' ] );
			$questionChoices = array_reverse( $questionChoices, true );
			$rankedChoices   = array_keys( $questionChoices );
			foreach ( $rankedChoices as $index => $choiceUid ) :
				$this->questions[ $question['uid'] ]['choices'][ $choiceUid ]['rank'] = $index + 1;
			endforeach;
		endforeach;

		// Fields
		$fields = $this->getSettingsItem( 'fields', [] );
		foreach ( $fields as &$field ) :
			// Translation
			if ( ! empty( $field['translations'][ $locale ]['label'] ) ) :
				$field['label'] = $field['translations'][ $locale ]['label'];
			endif;
			// Translation
			if ( ! empty( $field['translations'][ $locale ]['options'] ) ) :
				$field['options'] = $field['translations'][ $locale ]['options'];
			endif;

		endforeach;
		$this->setSettingsItem( 'fields', $fields );

		// Current page
		$this->currentPage = empty( $attributes['currentPage'] ) ? $this->currentPage : (int) $attributes['currentPage'];

		// Choice per page
		$this->choicesPerPage = (int) $this->getSettingsItem( 'design.pagination.perPage' ) ?: 10;

		// Sort choices
		$this->sortChoicesBy        = (string) $this->getSettingsItem( 'choices.sort.field', 'position' );
		$this->sortChoicesDirection = (string) $this->getSettingsItem( 'choices.sort.direction', 'desc' );

		// Sort results
		$this->sortResultsBy        = (string) $this->getSettingsItem( 'results.sort.field', 'position' );
		$this->sortResultsDirection = (string) $this->getSettingsItem( 'results.sort.direction', self::SORT_DESC );

		/**
		 * Filters the poll questions.
		 *
		 * @param  array  $questions  Questions array.
		 * @param  Model  $model  Poll model.
		 *
		 * @return array
		 * @since 4.0.1
		 */
		$this->questions = apply_filters( 'totalpoll/filters/poll/questions', $this->questions, $this );

		/**
		 * Filters the poll total votes.
		 *
		 * @param  int  $votes  Total votes.
		 * @param  Model  $model  Poll model.
		 *
		 * @return array
		 * @since 4.0.1
		 */
		$this->totalVotes = apply_filters( 'totalpoll/filters/poll/total-votes', $this->totalVotes, $this );

		// Limitations
		$this->limitations = new \TotalPollVendors\TotalCore\Limitations\Bag();

		// Period
		$periodArgs = $this->getSettingsItem( 'vote.limitations.period', [] );

		if ( ! empty( $periodArgs['enabled'] ) ) :
			$this->limitations->add( 'period', new \TotalPoll\Limitations\Period( $periodArgs ) );
		endif;

		// Membership
		$membershipArgs = $this->getSettingsItem( 'vote.limitations.membership', [] );
		if ( ! empty( $membershipArgs['enabled'] ) ) :
			$this->limitations->add( 'membership', new \TotalPoll\Limitations\Membership( $membershipArgs ) );
		endif;

		// Quota
		$quotaArgs = $this->getSettingsItem( 'vote.limitations.quota', [] );
		if ( ! empty( $quotaArgs['enabled'] ) ) :
			$quotaArgs['currentValue'] = $this->totalVotes;
			$this->limitations->add( 'quota', new \TotalPoll\Limitations\Quota( $quotaArgs ) );
		endif;

		// Region
		$regionArgs = $this->getSettingsItem( 'vote.limitations.region', [] );
		if ( ! empty( $regionArgs['enabled'] ) ) :
			$regionArgs['ip'] = $attributes['ip'];
			$this->limitations->add( 'region', new \TotalPoll\Limitations\Region( $regionArgs ) );
		endif;
		/**
		 * Fires after limitations setup.
		 *
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @since 4.0.0
		 */
		do_action( 'totalpoll/actions/poll/limitations', $this );

		// Restrictions
		$this->restrictions = new \TotalPollVendors\TotalCore\Restrictions\Bag();

		$frequencyArgs              = $this->getSettingsItem( 'vote.frequency', [ 'timeout' => 3600 ] );
		$frequencyArgs['uid']       = $this->getUid();
		$frequencyArgs['poll']      = $this;
		$frequencyArgs['action']    = 'vote';
		$frequencyArgs['fullCheck'] = TotalPoll()->option( 'performance.fullChecks.enabled' );

		$frequencyArgs = apply_filters( 'totalpoll/filters/poll/vote/frequency', $frequencyArgs, $this );

		if ( ! empty( $frequencyArgs['cookies']['enabled'] ) ) :
			$this->restrictions->add( 'cookies', new \TotalPoll\Restrictions\Cookies( $frequencyArgs ) );
		endif;

		if ( ! empty( $frequencyArgs['ip']['enabled'] ) ) :
			$this->restrictions->add( 'ip', new \TotalPoll\Restrictions\IPAddress( $frequencyArgs ) );
		endif;

		if ( ! empty( $frequencyArgs['user']['enabled'] ) ) :
			$this->restrictions->add( 'user', new \TotalPoll\Restrictions\LoggedInUser( $frequencyArgs ) );
		endif;

		/**
		 * Fires after restrictions setup.
		 *
		 * @param  ModelContract  $poll  Poll model object.
		 * @param  array  $frequencyArgs  Frequency arguments.
		 *
		 * @since 4.0.0
		 */
		do_action( 'totalpoll/actions/poll/restrictions', $this, $frequencyArgs );

		// Screen
		if ( $this->hasVoted() || ! $this->isAcceptingVotes() ) :
			$this->screen = self::RESULTS_SCREEN;
		endif;

		/**
		 * Fires after first screen setup.
		 *
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @since 4.0.0
		 */
		do_action( 'totalpoll/actions/poll/screen', $this );

		// Translation
		$this->setSettingsItem(
			'seo.poll.title',
			$this->getSettingsItem(
				"seo.poll.translations.{$locale}.title",
				$this->getSettingsItem( 'seo.poll.title' )
			)
		);

		$this->setSettingsItem(
			'seo.poll.description',
			$this->getSettingsItem(
				"seo.poll.translations.{$locale}.description",
				$this->getSettingsItem( 'seo.poll.description' )
			)
		);

		$this->setSettingsItem(
			'content.welcome.content',
			$this->getSettingsItem(
				"content.welcome.translations.{$locale}.content",
				$this->getSettingsItem( 'content.welcome.content' )
			)
		);

		$this->setSettingsItem(
			'content.vote.above',
			$this->getSettingsItem(
				"content.vote.translations.{$locale}.above",
				$this->getSettingsItem( 'content.vote.above' )
			)
		);

		$this->setSettingsItem(
			'content.vote.below',
			$this->getSettingsItem(
				"content.vote.translations.{$locale}.below",
				$this->getSettingsItem( 'content.vote.below' )
			)
		);

		$this->setSettingsItem(
			'content.thankyou.content',
			$this->getSettingsItem(
				"content.thankyou.translations.{$locale}.content",
				$this->getSettingsItem( 'content.thankyou.content' )
			)
		);

		$this->setSettingsItem(
			'content.results.above',
			$this->getSettingsItem(
				"content.results.translations.{$locale}.above",
				$this->getSettingsItem( 'content.results.above' )
			)
		);

		$this->setSettingsItem(
			'content.results.below',
			$this->getSettingsItem(
				"content.results.translations.{$locale}.below",
				$this->getSettingsItem( 'content.results.below' )
			)
		);

		$this->setSettingsItem(
			'results.message',
			$this->getSettingsItem(
				"results.translations.{$locale}.message",
				$this->getSettingsItem( 'results.message' )
			)
		);

		/**
		 * Fires after poll model setup is completed.
		 *
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @since 4.0.0
		 */
		do_action( 'totalpoll/actions/poll/setup', $this );
	}

	/**
	 * Get settings section or item.
	 *
	 * @param  bool  $section  Settings section.
	 * @param  bool  $args  Path to setting.
	 *
	 * @return mixed|array|null
	 * @since 1.0.0
	 */
	public function getSettings( $section = false, $args = false ) {
		// Deep selection.
		if ( $args !== false && $section && isset( $this->settings[ $section ] ) ) :
			$paths = func_get_args();
			unset( $paths[0] );

			return Arrays::getDeep( $this->settings[ $section ], $paths );
		endif;

		// Return specific settings section, otherwise, return all settings.
		if ( $section ) :
			return isset( $this->settings[ $section ] ) ? $this->settings[ $section ] : null;
		endif;

		return $this->settings;
	}

	/**
	 * @param  array  $settings
	 */
	public function setSettings( array $settings = [] ) {
		$this->settings = $settings;
	}

	/**
	 * Get settings item.
	 *
	 * @param  bool  $needle  Settings name.
	 * @param  bool  $default  Default value.
	 *
	 * @return mixed|array|null
	 * @since 1.0.0
	 */
	public function getSettingsItem( $needle, $default = null ) {
		/**
		 * Filters the poll settings item.
		 *
		 * @param  array  $settings  Poll settings.
		 * @param  string  $default  Default value.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return mixed
		 * @since 4.0.0
		 */
		return apply_filters(
			"totalpoll/filters/poll/settings-item/{$needle}",
			Arrays::getDotNotation( $this->settings, $needle, $default ),
			$this->settings,
			$default,
			$this
		);
	}

	/**
	 * Get poll post object.
	 *
	 * @return array|mixed|null|\WP_Post
	 */
	public function getPollPost() {
		return $this->pollPost;
	}

	/**
	 * Get poll id.
	 *
	 * @return int
	 * @since 1.0.0
	 */
	public function getId() {
		return (int) $this->id;
	}

	/**
	 * Get poll uid.
	 *
	 * @return int
	 * @since 4.1.3
	 */
	public function getUid() {
		return (string) $this->uid;
	}

	/**
	 * Get poll title.
	 *
	 * @return string
	 * @since 1.0.0
	 */
	public function getTitle() {
		return $this->pollPost->post_title;
	}

	/**
	 * Get seo attributes.
	 *
	 * @return array
	 * @since 1.0.0
	 */
	public function getSeoAttributes() {
		if ( $this->seo === null ) :
			$bindings = [
				'title'    => $this->getTitle(),
				'sitename' => get_bloginfo( 'name' ),
			];

			$this->seo = [
				'title'       => Strings::template( $this->getSettingsItem( 'seo.poll.title' ), $bindings ),
				'description' => Strings::template( $this->getSettingsItem( 'seo.poll.description' ), $bindings ),
			];
		endif;

		/**
		 * Filters the poll seo attributes.
		 *
		 * @param  array  $seo  SEO attributes.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/seo', $this->seo, $this );
	}

	/**
	 * Get share attributes.
	 *
	 * @return array
	 * @since 1.0.0
	 */
	public function getShareAttributes() {
		$websites     = array_filter( (array) TotalPoll()->option( 'share.websites', [] ) );
		$websitesUrls = [
			'facebook'  => 'https://www.facebook.com/sharer.php?u={{url}}',
			'twitter'   => 'https://twitter.com/intent/tweet?url={{url}}',
			'pinterest' => 'https://pinterest.com/pin/create/bookmarklet/?url={{url}}',
		];
		$shareUrlArgs = [
			'utm_source'   => '',
			'utm_medium'   => 'poll-share-button',
			'utm_campaign' => $this->getTitle(),
		];

		foreach ( $websitesUrls as $service => $websitesUrl ) :
			$shareUrlArgs['utm_source'] = $service;
			$shareUrl                   = add_query_arg( $shareUrlArgs, $this->getUrl() );
			$websitesUrls[ $service ]   = Strings::template( $websitesUrl, [ 'url' => urlencode( $shareUrl ) ] );
		endforeach;

		/**
		 * Filters the poll sharing attributes.
		 *
		 * @param  array  $attributes  Sharing attributes.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/share', array_intersect_key( $websitesUrls, $websites ), $this );
	}

	/**
	 * Get poll thumbnail.
	 *
	 * @return false|string
	 * @since 1.0.0
	 */
	public function getThumbnail() {
		$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $this->id ), 'post-thumbnail' );

		$thumbnail = empty( $thumbnail[0] ) ? TotalPoll()->env( 'url' ) . 'assets/dist/images/poll/no-preview.png' : $thumbnail[0];

		/**
		 * Filters the poll thumbnail.
		 *
		 * @param  array  $attributes  Poll model attributes.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return string
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/thumbnail', $thumbnail, $this );
	}

	/**
	 * Get time left to start.
	 *
	 * @return int|\DateInterval
	 * @since 1.0.0
	 */
	public function getTimeLeftToStart() {
		$startDate = $this->getSettingsItem( 'vote.limitations.period.start' );
		$startDate = $startDate ? TotalPoll( 'datetime', [ $startDate ] ) : false;

		if ( $startDate && $startDate->getTimestamp() > current_time( 'timestamp' ) ) :
			$now = TotalPoll( 'datetime' );

			return $startDate->diff( $now, true );
		endif;

		return 0;
	}

	/**
	 * Get time left to end.
	 *
	 * @return int|\DateInterval
	 * @since 1.0.0
	 */
	public function getTimeLeftToEnd() {
		$endDate = $this->getSettingsItem( 'vote.limitations.period.end' );
		$endDate = $endDate ? TotalPoll( 'datetime', [ $endDate ] ) : false;

		if ( $endDate && $endDate->getTimestamp() > current_time( 'timestamp' ) ) :
			$now = TotalPoll( 'datetime' );

			return $endDate->diff( $now, true );
		endif;

		return 0;
	}

	/**
	 * Get form.
	 *
	 * @return Form Form object
	 * @since 1.0.0
	 */
	public function getForm() {
		if ( $this->form === null ) :
			$this->form = TotalPoll( 'polls.form', [ $this ] );
		endif;

		return $this->form;
	}

	/**
	 * Get URL.
	 *
	 * @param  array  $args
	 *
	 * @return string
	 * @since 1.0.0
	 */
	public function getUrl( $args = [] ) {
		$base = $this->getPermalink();

		if ( ! is_singular( TP_POLL_CPT_NAME ) ) {
			$base = wp_get_referer() ?: TotalPoll( 'http.request' )->request( 'totalpoll.referer' ) ?: $base;
		}

		$url = esc_url( add_query_arg( $args, $base ) );

		/**
		 * Filters the poll urls.
		 *
		 * @param  string  $url  URL.
		 * @param  array  $args  Arguments.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return string
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/url', $url, $args, $this );
	}

	/**
	 * Get action.
	 *
	 * @return string
	 * @since 1.0.0
	 */
	public function getAction() {
		return $this->action;
	}

	/**
	 * Get AJAX url.
	 *
	 * @param  array  $args
	 *
	 * @return string
	 */
	public function getAjaxUrl( $args = [] ) {
		$args          = Arrays::parse(
			$args,
			[
				'pollId' => $this->id,
				'action' => $this->getAction(),
				'screen' => $this->getScreen(),
			]
		);
		$base          = admin_url( 'admin-ajax.php' );
		$urlParameters = [ 'action' => 'totalpoll', 'totalpoll' => $args ];

		$url = esc_url( add_query_arg( $urlParameters, $base ) );

		/**
		 * Filters the poll AJAX urls.
		 *
		 * @param  string  $url  URL.
		 * @param  array  $args  Arguments.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return string
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/ajax-url', $url, $args, $this );
	}

	/**
	 * Get poll permalink.
	 *
	 * @return false|string
	 */
	public function getPermalink() {
		return get_permalink( $this->pollPost );
	}

	/**
	 * Get poll total votes.
	 *
	 * @return int
	 * @since 1.0.0
	 */
	public function getTotalVotes() {
		return $this->totalVotes;
	}

	/**
	 * @return string
	 */
	public function getTotalVotesNumber() {
		return number_format( $this->totalVotes );
	}

	/**
	 * @return string
	 */
	public function getTotalVotesWithLabel() {
		return sprintf(
			_n( '%s Vote', '%s Votes', $this->totalVotes, 'totalpoll' ),
			number_format( $this->totalVotes )
		);
	}

	/**
	 * @param  null  $orderBy
	 * @param  string  $direction
	 *
	 * @return array
	 */
	public function getQuestions( $orderBy = null, $direction = self::SORT_ASC ) {
		if ( $orderBy ) :
			foreach ( $this->questions as &$question ) :
				uasort( $question['choices'], [ $this, 'orderBy' . ucfirst( $orderBy ) ] );

				if ( $direction && strtolower( $direction ) === self::SORT_DESC ) :
					$question['choices'] = array_reverse( $question['choices'], true );
				endif;
			endforeach;
		endif;

		return $this->questions;
	}

	/**
	 * @return array
	 */
	public function getQuestionsForVote() {
		/**
		 * Filters the poll questions (for vote).
		 *
		 * @param  array  $questions  Questions array.
		 * @param  Model  $model  Poll model.
		 *
		 * @return array
		 * @since 4.0.1
		 */
		return apply_filters(
			'totalpoll/filters/poll/questions-for-vote',
			$this->getQuestions( $this->sortChoicesBy, $this->sortChoicesDirection ),
			$this
		);
	}

	/**
	 * @return array
	 */
	public function getQuestionsForResults() {
		/**
		 * Filters the poll questions (for results).
		 *
		 * @param  array  $questions  Questions array.
		 * @param  Model  $model  Poll model.
		 *
		 * @return array
		 * @since 4.0.1
		 */
		return apply_filters(
			'totalpoll/filters/poll/questions-for-results',
			$this->getQuestions( $this->sortResultsBy, $this->sortResultsDirection ),
			$this
		);
	}

	/**
	 * @return int
	 */
	public function getQuestionsCount() {
		return count( $this->questions );
	}

	/**
	 * @return int
	 */
	public function getChoicesCount() {
		return count( $this->choicesMap );
	}

	/**
	 * @param $questionUid
	 *
	 * @return int
	 */
	public function getQuestionChoicesCount( $questionUid ) {
		return empty( $this->questions[ $questionUid ] ) ? 0 : count( $this->questions[ $questionUid ]['choices'] );
	}

	/**
	 * @param $questionUid
	 *
	 * @return array|mixed|null
	 */
	public function getQuestion( $questionUid ) {
		return empty( $this->questions[ $questionUid ] ) ? null : $this->questions[ $questionUid ];
	}

	/**
	 * @param $questionUid
	 *
	 * @return array
	 */
	public function getQuestionChoices( $questionUid ) {
		return empty( $this->questions[ $questionUid ] ) ? [] : $this->questions[ $questionUid ]['choices'];
	}

	/**
	 * @param $questionUid
	 *
	 * @return int
	 */
	public function getQuestionVotes( $questionUid ) {
		return empty( $this->questions[ $questionUid ] ) ? 0 : $this->questions[ $questionUid ]['votes'];
	}

	/**
	 * @param $questionUid
	 *
	 * @return string
	 */
	public function getQuestionVotesWithLabel( $questionUid ) {
		$votes = $this->getQuestionVotes( $questionUid );

		return sprintf( _n( '%s Vote', '%s Votes', $votes, 'totalpoll' ), number_format( $votes ) );
	}

	/**
	 * @param $choiceUid
	 *
	 * @return array|mixed|null
	 */
	public function getQuestionUidByChoiceUid( $choiceUid ) {
		return empty( $this->choicesMap[ $choiceUid ] ) ? null : $this->choicesMap[ $choiceUid ];
	}

	/**
	 * @param $choiceUid
	 *
	 * @return array|null
	 */
	public function getChoice( $choiceUid ) {
		return empty( $this->choicesMap[ $choiceUid ] ) ? null : $this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ];
	}

	/**
	 * @param $choiceUid
	 *
	 * @return int|null
	 */
	public function getChoiceVotes( $choiceUid ) {
		if ( ! isset( $this->choicesMap[ $choiceUid ] ) ) :
			return null;
		endif;

		return $this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ]['votes'];
	}

	/**
	 * @param $choiceUid
	 *
	 * @return null|string
	 */
	public function getChoiceVotesNumber( $choiceUid ) {
		if ( ! isset( $this->choicesMap[ $choiceUid ] ) ) :
			return null;
		endif;

		$votes = $this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ]['votes'];

		return number_format( $votes );
	}

	/**
	 * @param $choiceUid
	 *
	 * @return null|string
	 */
	public function getChoiceVotesWithLabel( $choiceUid ) {
		if ( ! isset( $this->choicesMap[ $choiceUid ] ) ) :
			return null;
		endif;

		$votes = $this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ]['votes'];

		return sprintf( _n( '%s Vote', '%s Votes', $votes, 'totalpoll' ), number_format( $votes ) );
	}

	/**
	 * @param $choiceUid
	 *
	 * @return null|string
	 */
	public function getChoiceVotesPercentage( $choiceUid ) {
		if ( ! isset( $this->choicesMap[ $choiceUid ] ) ) :
			return null;
		endif;

		$votes      = $this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ]['votes'];
		$totalVotes = $this->questions[ $this->choicesMap[ $choiceUid ] ]['votes'];

		$percentage = $totalVotes ? number_format( ( $votes / $totalVotes ) * 100, 2 ) : '0.00';

		return apply_filters(
			'totalpoll/filters/poll/choice/percentage',
			$percentage,
			$votes,
			$totalVotes,
			$choiceUid,
			$this
		);
	}

	/**
	 * @param $choiceUid
	 *
	 * @return string
	 */
	public function getChoiceVotesPercentageWithLabel( $choiceUid ) {
		return $this->getChoiceVotesPercentage( $choiceUid ) . '%';
	}

	/**
	 * @param $choiceUid
	 *
	 * @return string
	 */
	public function getChoiceVotesFormatted( $choiceUid ) {
		$format = apply_filters(
			'totalpoll/filters/poll/choice/votes/format',
			$this->getSettingsItem( 'results.format', '{{votesWithLabel}}' ),
			$choiceUid,
			$this
		);
		$vars   = apply_filters(
			'totalpoll/filters/poll/choice/votes/args',
			[
				'votes'               => $this->getChoiceVotesNumber( $choiceUid ),
				'votesPercentage'     => $this->getChoiceVotesPercentageWithLabel( $choiceUid ),
				'votesWithLabel'      => $this->getChoiceVotesWithLabel( $choiceUid ),
				'votesTotal'          => $this->getQuestionVotes( $this->getQuestionUidByChoiceUid( $choiceUid ) ),
				'votesTotalWithLabel' => $this->getQuestionVotesWithLabel( $this->getQuestionUidByChoiceUid( $choiceUid ) ),
			],
			$choiceUid,
			$this
		);

		return Strings::template( $format, $vars );
	}

	/**
	 * @return array
	 */
	public function getChoices() {
		$choices = [];
		foreach ( $this->choicesMap as $choiceUid => $questionUid ) :
			$choices[ $choiceUid ] = $this->questions[ $questionUid ]['choices'][ $choiceUid ];
		endforeach;

		return $choices;
	}

	/**
	 * @param  array  $args
	 *
	 * @return array
	 */
	public function getChoicesRows( $args = [] ) {
		$perRow  = $this->getSettingsItem( 'design.layout.columns', 4 );
		$choices = $this->getChoices();

		return $perRow === 0 ? [ $choices ] : array_chunk( $choices, $perRow, true );
	}

	/**
	 * @return float|int|string
	 */
	public function getColumnWidth() {
		$perRow = $this->getSettingsItem( 'design.layout.columns', 4 );

		return 100 / $perRow;
	}

	/**
	 * @return null|\WP_Error
	 */
	public function getError() {
		return $this->error;
	}

	/**
	 * @return null|string
	 */
	public function getErrorMessage() {
		return is_wp_error( $this->error ) ? $this->error->get_error_message() : null;
	}

	/**
	 * @return \TotalPollVendors\TotalCore\Contracts\Limitations\Bag|\TotalPollVendors\TotalCore\Limitations\Bag
	 */
	public function getLimitations() {
		return $this->limitations;
	}

	/**
	 * @return \TotalPollVendors\TotalCore\Contracts\Restrictions\Bag|\TotalPollVendors\TotalCore\Restrictions\Bag
	 */
	public function getRestrictions() {
		return $this->restrictions;
	}

	/**
	 * @return array
	 */
	public function getFields() {
		$fields = $this->getSettingsItem( 'fields', [] );
		foreach ( $fields as $fieldIndex => $field ) :
			$fields[ $field['uid'] ] = [
				'type'         => $field['type'],
				'label'        => $field['label'],
				'name'         => $field['name'],
				'defaultValue' => $field['defaultValue'],
				'options'      => $field['options'],
				'required'     => ! empty( $field['validations']['filled']['enabled'] ),
			];
			unset( $fields[ $fieldIndex ] );
		endforeach;

		/**
		 * Filters the poll custom fields.
		 *
		 * @param  array  $fields  Poll custom fields.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/fields', $fields, $this );
	}


	/**
	 * Get prefix.
	 *
	 * @param  string  $append
	 *
	 * @return string
	 * @since 1.0.0
	 */
	public function getPrefix( $append = '' ) {
		/**
		 * Filters poll prefix.
		 *
		 * @param  string  $prefix  Poll prefix.
		 * @param  string  $append  Appended value.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.3
		 */
		return apply_filters( 'totalpoll/filters/poll/prefix', "tp_{$this->id}_{$append}", $append, $this );
	}

	/**
	 * Get current screen.
	 *
	 * @return string Current screen.
	 * @since 1.0.0
	 */
	public function getScreen() {
		return $this->screen;
	}

	/**
	 * @return string
	 */
	public function getHeader() {
		$header = '';

		if ( $this->isVoteScreen() ) :
			$header .= $this->getAboveVoteContent();
		elseif ( $this->isResultsScreen() ) :
			$header .= $this->getAboveResultsContent();
		endif;

		return do_shortcode( $header );
	}

	/**
	 * @return string
	 */
	public function getFooter() {
		$footer = '';

		if ( $this->isVoteScreen() ) :
			$footer .= $this->getBelowVoteContent();
		elseif ( $this->isResultsScreen() ) :
			$footer .= $this->getBelowResultsContent();
		endif;

		return do_shortcode( $footer );
	}

	/**
	 * @return string
	 */
	public function getWelcomeContent() {
		return $this->getSettingsItem( 'content.welcome.content' );
	}

	/**
	 * @return string
	 */
	public function getThankyouContent() {
		return $this->getSettingsItem( 'content.thankyou.content' );
	}

	/**
	 * @return string
	 */
	public function getAboveVoteContent() {
		return $this->getSettingsItem( 'content.vote.above' );
	}

	/**
	 * @return string
	 */
	public function getBelowVoteContent() {
		return $this->getSettingsItem( 'content.vote.below' );
	}

	/**
	 * @return string
	 */
	public function getAboveResultsContent() {
		return $this->getSettingsItem( 'content.results.above' );
	}

	/**
	 * @return string
	 */
	public function getBelowResultsContent() {
		return $this->getSettingsItem( 'content.results.below' );
	}

	/**
	 * @return string
	 */
	public function getHiddenResultsContent() {
		return apply_filters(
			'totalpoll/filters/poll/results-hidden/message',
			$this->hasVoted() ? $this->getSettingsItem( 'results.message' ) : '',
			$this
		);
	}

	/**
	 * @return string
	 */
	public function getTemplateId() {
		return $this->getSettingsItem( 'design.template', 'basic-template' );
	}

	/**
	 * @return string
	 */
	public function getPresetUid() {
		return $this->getSettingsItem( 'presetUid', md5( $this->getId() ) );
	}

	/**
	 * Edit link in WordPress dashboard.
	 *
	 * @return string
	 */
	public function getAdminEditLink() {
		return admin_url( "post.php?post={$this->getId()}&action=edit" );
	}

	/**
	 * @param  string  $format
	 *
	 * @return string|void
	 */
	public function getAdminExportAsLink( $format = 'csv' ) {
		$url = sprintf(
			'admin-ajax.php?action=%s&poll=%d&format=%s',
			'totalpoll_insights_download',
			$this->getId(),
			strtolower( (string) $format )
		);

		return admin_url( $url );
	}

	/**
	 * Set/Override settings item value.
	 *
	 * @param $needle
	 * @param $value
	 *
	 * @return void
	 */
	public function setSettingsItem( $needle, $value ) {
		$this->settings = Arrays::setDotNotation( $this->settings, $needle, $value );
	}

	/**
	 * Set current screen.
	 *
	 * @param $screen string Screen name.
	 *
	 * @return $this
	 * @since 1.0.0
	 */
	public function setScreen( $screen ) {
		$this->screen = esc_html( (string) $screen );

		return $this;
	}

	/**
	 * Set action.
	 *
	 * @param  string  $action
	 */
	public function setAction( $action ) {
		$this->action = sanitize_text_field( (string) $action );
	}

	/**
	 * Get received choices.
	 *
	 * @return array
	 */
	public function getReceivedChoices() {
		$choices = [];
		foreach ( $this->choicesMap as $choiceId => $questionUid ) :
			$choice = $this->questions[ $questionUid ]['choices'][ $choiceId ];
			if ( ! empty( $choice['receivedVotes'] ) ) :
				$choices[ $choiceId ] = $choice;
			endif;
		endforeach;

		return $choices;
	}

	public function getReceivedQuestions() {
		$questions = [];
		foreach ( $this->choicesMap as $choiceId => $questionUid ) :
			$choice = $this->questions[ $questionUid ]['choices'][ $choiceId ];
			if ( ! empty( $choice['receivedVotes'] ) ) :
				$questions[ $questionUid ] = true;
			endif;
		endforeach;

		return array_keys( $questions );
	}

	/**
	 * Set form.
	 *
	 * @param  Form  $form
	 *
	 * @return Form Form object
	 * @since 1.0.0
	 */
	public function setForm( Form $form ) {
		return $this->form = $form;
	}

	/**
	 * Set an error.
	 *
	 * @param  \WP_Error  $error
	 *
	 * @since 1.0.0
	 */
	public function setError( $error ) {
		$this->error = $error;
	}

	/**
	 * @return bool
	 */
	public function hasError() {
		return ! empty( $this->error );
	}

	/**
	 * @return bool
	 */
	public function hasVoted() {
		/**
		 * Filters whether current user has voted before.
		 *
		 * @param  bool  $hasVoted  Whether current user has voted or not.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return array
		 * @since 4.0.0
		 */
		return apply_filters(
			'totalpoll/filters/poll/has-voted',
			is_wp_error(
				$this->getRestrictions()
				     ->check()
			) || $this->getRestrictions()
			          ->isApplied() || did_action( 'totalpoll/actions/after/poll/command/vote' ),
			$this
		);
	}

	/**
	 * @return bool
	 */
	public function hasWelcomeContent() {
		return ! empty( $this->settings['content']['welcome']['content'] );
	}

	/**
	 * @return bool
	 */
	public function hasThankyouContent() {
		return ! empty( $this->settings['content']['thankyou']['content'] );
	}

	/**
	 * @return bool
	 */
	public function hasAboveVoteContent() {
		return ! empty( $this->settings['content']['vote']['above'] );
	}

	/**
	 * @return bool
	 */
	public function hasBelowVoteContent() {
		return ! empty( $this->settings['content']['vote']['below'] );
	}

	/**
	 * @return bool
	 */
	public function hasAboveResultsContent() {
		return ! empty( $this->settings['content']['results']['above'] );
	}

	/**
	 * @return bool
	 */
	public function hasBelowResultsContent() {
		return ! empty( $this->settings['content']['results']['below'] );
	}

	/**
	 * Is poll accepting votes.
	 *
	 * @return bool
	 */
	public function isAcceptingVotes() {
		$limited = $this->getLimitations()
		                ->check();
		if ( is_wp_error( $limited ) ) :
			$this->error = $limited;
		else :
			$restricted = $this->getRestrictions()
			                   ->check();
			if ( is_wp_error( $restricted ) ) :
				$this->error = $restricted;
			endif;
		endif;

		/**
		 * Filters whether the poll is accepting new votes or not.
		 *
		 * @param  bool  $acceptVotes  True when new votes are accepted otherwise false.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return bool
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/accept-vote', ! is_wp_error( $this->error ), $this );
	}

	/**
	 * Is poll results hidden.
	 *
	 * @return bool
	 */
	public function isResultsHidden() {
		$visibility = $this->getSettingsItem( 'results.visibility' );

		
		$hidden = $visibility === 'voters' && !$this->hasVoted();
		

		


		/**
		 * Filters the poll results visibility.
		 *
		 * @param  bool  $hidden  True when hidden otherwise false.
		 * @param  ModelContract  $poll  Poll model object.
		 *
		 * @return bool
		 * @since 4.0.0
		 */
		return apply_filters( 'totalpoll/filters/poll/results-hidden', $hidden, $this );
	}

	/**
	 * @return bool
	 */
	public function isPaginated() {
		return ! empty( $this->choicesPerPage );
	}

	/**
	 * @param     $choiceUid
	 * @param  int  $by
	 *
	 * @return bool|null
	 */
	public function incrementChoiceVotes( $choiceUid, $by = 1 ) {
		if ( ! isset( $this->choicesMap[ $choiceUid ] ) ) :
			return null;
		endif;

		$this->questions[ $this->choicesMap[ $choiceUid ] ]['votes']                                  += $by;
		$this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ]['votes']         += $by;
		$this->questions[ $this->choicesMap[ $choiceUid ] ]['choices'][ $choiceUid ]['receivedVotes'] += $by;
		$this->questions[ $this->choicesMap[ $choiceUid ] ]['receivedVotes']                          += $by;

		return true;
	}

	/**
	 * @return bool
	 */
	public function isPasswordProtected() {
		return post_password_required( $this->pollPost );
	}

	/**
	 * @return bool
	 */
	public function isMigrated() {
		return get_post_meta( $this->id, '_migrated', true ) || ! get_post_meta( $this->id, '_preset_id', true );
	}

	/*
	 * Load and apply user-provided expressions.
	 *
	 * @return void
	 */
	public function applyPollExpressions() {
		$locale         = get_locale();
		$localeFallback = substr( $locale, 0, 2 );

		if ( ! is_admin() || Misc::isDoingAjax() ) :
			// Get expressions from the model
			// Check if there are expressions using the full locale (i.e. en_US, ar_AR, etc..)
			// If not, we fall back to short locale (en, ar, etc..), otherwise an empty array
			$expressions = Arrays::getDotNotation(
				$this->settings,
				"expressions.{$locale}",
				Arrays::getDotNotation( $this->settings, "expressions.{$localeFallback}", [] )
			);

			if ( ! empty( $expressions ) && ! empty( $GLOBALS['l10n']['totalpoll'] ) ):
				$domain                    = $GLOBALS['l10n']['totalpoll'];
				self::$originalExpressions = unserialize( serialize( $domain ) );

				foreach ( $expressions as $expression => $expressionContent ) :
					if ( empty( $expressionContent['translations'] ) || empty( $expressionContent['translations'][0] ) ) :
						continue;
					endif;

					if ( empty( $domain->entries[ $expression ] ) ) :
						$entry = new \Translation_Entry(
							[
								'singular'     => $expression,
								'translations' => $expressionContent['translations'],
							]
						);
						$domain->add_entry( $entry );
					else :
						$domain->entries[ $expression ]->translations = $expressionContent['translations'];
					endif;
				endforeach;
			endif;
		endif;
	}

	/*
	 * Restore global poll expressions to avoid affecting other polls.
	 *
	 * @return void
	 */
	protected function restorePollExpressions() {
		if ( self::$originalExpressions ):
			$GLOBALS['l10n']['totalpoll'] = self::$originalExpressions;
		endif;
	}

	/**
	 * Render poll.
	 *
	 * @return string
	 * @since 1.0.0
	 */

	public function render() {
		if ( $this->isPasswordProtected() ) :
			return '';
		endif;

		$this->applyPollExpressions();
		$renderedPoll = TotalPoll( 'polls.renderer', [ $this ] )->render();
		$this->restorePollExpressions();

		return $renderedPoll;
	}

	/**
	 * JSON representation of poll.
	 *
	 * @return array
	 * @since 1.0.0
	 */
	#[\ReturnTypeWillChange]
	public function jsonSerialize() {
		return $this->toArray();
	}

	/**
	 * Get the instance as an array.
	 *
	 * @return array
	 */
	public function toArray() {
		$poll = [
			'id'            => $this->getId(),
			'title'         => $this->getTitle(),
			'permalink'     => $this->getPermalink(),
			'questions'     => $this->getQuestions(),
			'fields'        => $this->getFields(),
			'receivedVotes' => $this->getReceivedChoices(),
		];

		if ( is_admin() ) :
			$poll['admin'] = [
				'editLink' => $this->getAdminEditLink(),
			];
		endif;

		return $poll;
	}

	/**
	 * @param  mixed  $offset
	 *
	 * @return bool
	 */
	#[\ReturnTypeWillChange]
	public function offsetExists( $offset ) {
		return isset( $this->{$offset} );
	}

	/**
	 * @param  mixed  $offset
	 *
	 * @return mixed
	 */
	#[\ReturnTypeWillChange]
	public function offsetGet( $offset ) {
		return isset( $this->{$offset} ) ? $this->{$offset} : null;
	}

	/**
	 * @param  mixed  $offset
	 * @param  mixed  $value
	 */
	#[\ReturnTypeWillChange]
	public function offsetSet( $offset, $value ) {
	}

	/**
	 * @param  mixed  $offset
	 */
	#[\ReturnTypeWillChange]
	public function offsetUnset( $offset ) {
	}

	/**
	 * Order by votes.
	 *
	 * @param $current
	 * @param $next
	 *
	 * @return int
	 * @since 1.0.0
	 */
	private function orderByVotes( $current, $next ) {
		if ( $current['votes'] === $next['votes'] ) :
			return 0;
		elseif ( $current['votes'] < $next['votes'] ) :
			return - 1;
		else :
			return 1;
		endif;
	}

	/**
	 * Order by label.
	 *
	 * @param $current
	 * @param $next
	 *
	 * @return int
	 * @since 1.0.0
	 */
	private function orderByLabel( $current, $next ) {
		
		return 0;
		

		
	}

	/**
	 * Shuffle.
	 *
	 * @param $current
	 * @param $next
	 *
	 * @return int
	 * @since 1.0.0
	 */
	private function orderByRandom( $current, $next ) {
		
		return 0;
		

		
	}

	/**
	 * Order by original position.
	 *
	 * @param $current
	 * @param $next
	 *
	 * @return int
	 * @since 1.0.0
	 */
	private function orderByPosition( $current, $next ) {
		if ( $current['index'] === $next['index'] ) :
			return 0;
		elseif ( $current['index'] < $next['index'] ) :
			return - 1;
		else :
			return 1;
		endif;
	}

	/**
	 * @param  array  $question
	 * @param  array  $choices
	 *
	 * @return mixed|void
	 */
	public function addQuestion( $question, $choices = [] ) {
		// TODO: Implement addQuestion() method.
	}

	/**
	 * @param  array  $choice
	 * @param  string  $questionUid
	 * @param  bool  $persistent
	 *
	 * @return array|bool
	 */
	public function addChoice( $choice, $questionUid, $persistent = true ) {
		$question = $this->getQuestion( $questionUid );
		$choice   = Arrays::parse(
			$choice,
			[
				'uid'           => 'custom-' . Misc::generateUid(),
				'type'          => 'text',
				'label'         => '',
				'visibility'    => true,
				'votes'         => 0,
				'votesOverride' => 0,
			]
		);

		if ( $question ) :
			if ( $persistent ) :
				$this->settings['questions'][ $question['index'] ]['choices'][] = $choice;
			endif;

			// Add to choices map
			$this->choicesMap[ $choice['uid'] ] = $question['uid'];
			$choice['index']                    = count( $this->settings['questions'][ $question['index'] ]['choices'] ) - 1;
			$choice['questionUid']              = $question['uid'];
			$choice['receivedVotes']            = 0;

			// Cumulative of votes for question
			$this->questions[ $question['uid'] ]['votes']                     += $choice['votes'];
			$this->totalVotes                                                 += $choice['votes'];
			$this->questions[ $question['uid'] ]['choices'][ $choice['uid'] ] = $choice;
		else :
			return false;
		endif;

		return $choice;
	}

	/**
	 * @inheritDoc
	 */
	public function save() {
		// Remove WP filters
		if ( function_exists( 'wp_remove_targeted_link_rel_filters' ) ) {
			wp_remove_targeted_link_rel_filters();
		}

		return ! is_wp_error(
			wp_update_post(
				[
					'ID'           => $this->getId(),
					'post_content' => wp_slash( json_encode( $this->settings, JSON_UNESCAPED_SLASHES ) ),
				]
			)
		);
	}

	/**
	 * @inheritDoc
	 */
	public function refreshUid() {
		$this->setSettingsItem( 'uid', Misc::generateUid() );

		return $this->save();
	}

	/**
	 * @param $criteria
	 *
	 * @return array
	 */
	public function getQuestionsWhere( $criteria ) {
		return array_filter(
			$this->questions,
			function ( $question ) use ( $criteria ) {
				foreach ( $criteria as $key => $value ) :
					if ( ! isset( $question[ $key ] ) || $question[ $key ] != $value ) :
						return false;
					endif;
				endforeach;

				return true;
			}
		);
	}

	/**
	 * @param $criteria
	 *
	 * @return array
	 */
	public function getChoicesWhere( $criteria ) {
		return array_filter(
			$this->choicesMap,
			function ( $question ) use ( $criteria ) {
				foreach ( $criteria as $key => $value ) :
					if ( ! isset( $question[ $key ] ) || $question[ $key ] != $value ) :
						return false;
					endif;
				endforeach;

				return true;
			}
		);
	}

	/**
	 * Set question.
	 *
	 * @param  string  $questionUid
	 * @param  array  $override
	 * @param  bool  $persistent
	 *
	 * @return bool
	 */
	public function setQuestion( $questionUid, $override = [], $persistent = true ) {
		$question = $this->getQuestion( $questionUid );
		if ( $question ) :
			$this->questions[ $question['uid'] ] = Arrays::parse( $override, $question );

			if ( $persistent ) :
				$this->settings['questions'][ $question['index'] ] = Arrays::parse(
					$override,
					$this->settings['questions'][ $question['index'] ]
				);
			endif;

			return true;
		endif;

		return false;
	}

	/**
	 * Set choice.
	 *
	 * @param  string  $choiceUid
	 * @param  array  $override
	 * @param  bool  $persistent
	 *
	 * @return bool
	 */
	public function setChoice( $choiceUid, $override = [], $persistent = true ) {
		$choice = $this->getChoice( $choiceUid );
		if ( $choice ) :
			$question = $this->getQuestion( $choice['questionUid'] );

			$this->questions[ $question['uid'] ]['choices'][ $choice['uid'] ] = Arrays::parse( $override, $choice );

			if ( $persistent ) :
				$this->settings['questions'][ $question['index'] ]['choices'][ $choice['index'] ] = Arrays::parse(
					$override,
					$this->settings['questions'][ $question['index'] ]['choices'][ $choice['index'] ]
				);
			endif;

			return true;
		endif;

		return false;
	}

	/**
	 * Remove question.
	 *
	 * @param  string  $questionUid
	 * @param  bool  $persistent
	 *
	 * @return bool
	 */
	public function removeQuestion( $questionUid, $persistent = true ) {
		$question = $this->getQuestion( $questionUid );
		if ( $question ) :
			foreach ( $question['choices'] as $choiceUid => $choice ) :
				$this->removeChoice( $choiceUid, $persistent );
			endforeach;

			if ( $persistent ) :
				unset( $this->settings['questions'][ $question['index'] ] );
			endif;

			return true;
		endif;

		return false;
	}

	/**
	 * Remove choice.
	 *
	 * @param  string  $choiceUid
	 * @param  bool  $persistent
	 *
	 * @return bool
	 */
	public function removeChoice( $choiceUid, $persistent = true ) {
		$choice = $this->getChoice( $choiceUid );
		if ( $choice ) :
			$question = $this->getQuestion( $choice['questionUid'] );

			unset( $this->questions[ $question['uid'] ]['choices'][ $choice['uid'] ], $this->choicesMap[ $choice['uid'] ] );

			if ( $persistent ) :
				unset( $this->settings['questions'][ $question['index'] ]['choices'][ $choice['index'] ] );
			endif;

			return true;
		endif;

		return false;
	}

	/**
	 * @param  string  $screen
	 *
	 * @return bool
	 */
	public function isScreen( $screen ) {
		return $this->screen === $screen;
	}

	/**
	 * @return bool
	 */
	public function isWelcomeScreen() {
		return $this->isScreen( self::WELCOME_SCREEN );
	}

	/**
	 * @return bool
	 */
	public function isVoteScreen() {
		return $this->isScreen( self::VOTE_ACTION );
	}

	/**
	 * @return bool
	 */
	public function isThankYouScreen() {
		return $this->isScreen( self::THANKYOU_SCREEN );
	}

	/**
	 * @return bool
	 */
	public function isResultsScreen() {
		return $this->isScreen( self::RESULTS_SCREEN );
	}

	/**
	 * @return array
	 */
	public function getViewVariables() {
		$variables = [
			'totalVotes'          => number_format_i18n( $this->getTotalVotes() ),
			'totalVotesWithLabel' => sprintf(
				_n( '%s vote', '%s votes', $this->getTotalVotes(), 'totalpoll' ),
				number_format_i18n( $this->getTotalVotes() )
			),
		];

		$questions = $this->getQuestions();

		$questionIndex = 0;

		foreach ( $questions as $question ) :
			$questionIndex ++;

			$votes                                                       = $this->getQuestionVotes( $question['uid'] );
			$variables["totalVotesForQuestion{$questionIndex}"]          = number_format_i18n( $votes );
			$variables["totalVotesWithLabelForQuestion{$questionIndex}"] = sprintf(
				_n(
					'%s vote',
					'%s votes',
					$votes,
					'totalpoll'
				),
				number_format_i18n( $votes )
			);
		endforeach;

		return apply_filters( 'totalpoll/filters/poll/view-variables', $variables, $this );
	}


	/**
	 * Check if choice was checked.
	 *
	 * @param $choiceUid
	 *
	 * @return bool
	 */
	public function isChoiceChecked( $choiceUid ) {
		return !empty($this->getChoice($choiceUid)['receivedVotes']);
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit