Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,39 +11,50 @@
|
||||
namespace IPS\Poll\Api\GraphQL;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Api\GraphQL\SafeException;
|
||||
use IPS\Member;
|
||||
use IPS\Poll;
|
||||
use IPS\Poll\Vote;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Base mutator class for polls
|
||||
*/
|
||||
class _PollMutator
|
||||
class PollMutator
|
||||
{
|
||||
/**
|
||||
* Vote in a poll
|
||||
*
|
||||
* @param \IPS\Poll $poll Poll reference
|
||||
* @return void
|
||||
* @param Poll $poll Poll reference
|
||||
* @param array|null $votes
|
||||
* @return void
|
||||
*/
|
||||
protected function _vote( $poll, $votes )
|
||||
protected function _vote( Poll $poll, ?array $votes ) : void
|
||||
{
|
||||
if( !$poll instanceof \IPS\Poll )
|
||||
if( !$poll instanceof Poll )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_POLL', 'GQL/0007/1', 403 );
|
||||
throw new SafeException( 'INVALID_POLL', 'GQL/0007/1', 403 );
|
||||
}
|
||||
|
||||
if( !$poll->canVote() )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'CANNOT_VOTE', 'GQL/0007/2', 403 );
|
||||
throw new SafeException( 'CANNOT_VOTE', 'GQL/0007/2', 403 );
|
||||
}
|
||||
|
||||
// A null vote is viewing the results and forfeiting the ability to vote again
|
||||
if( $votes === NULL || !\count( $votes ) )
|
||||
if( $votes === NULL || !count( $votes ) )
|
||||
{
|
||||
$vote = \IPS\Poll\Vote::fromForm( NULL );
|
||||
$vote = Vote::fromForm( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -52,12 +63,12 @@ class _PollMutator
|
||||
// Rebuild the vote array to match form input
|
||||
foreach( $votes as $vote )
|
||||
{
|
||||
if( \is_array( $vote['choices'] ) )
|
||||
if( is_array( $vote['choices'] ) )
|
||||
{
|
||||
if( \count( $vote['choices'] ) === 1 )
|
||||
if( count( $vote['choices'] ) === 1 )
|
||||
{
|
||||
// When coming from a form we save this as a string without typecasting first, so replicating here for consistency
|
||||
$choice = (string) \intval( $vote['choices'][0] );
|
||||
$choice = (string) intval( $vote['choices'][0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -67,15 +78,15 @@ class _PollMutator
|
||||
else
|
||||
{
|
||||
// When coming from a form we save this as a string without typecasting first, so replicating here for consistency
|
||||
$choice = (string) \intval( $vote['choices'] );
|
||||
$choice = (string) intval( $vote['choices'] );
|
||||
}
|
||||
|
||||
$voteAsForm[ $vote['id'] ] = $choice;
|
||||
}
|
||||
|
||||
$vote = \IPS\Poll\Vote::fromForm( $voteAsForm );
|
||||
$vote = Vote::fromForm( $voteAsForm );
|
||||
}
|
||||
|
||||
$poll->addVote( $vote, \IPS\Member::loggedIn() );
|
||||
$poll->addVote( $vote, Member::loggedIn() );
|
||||
}
|
||||
}
|
||||
+20
-13
@@ -12,9 +12,16 @@
|
||||
namespace IPS\Poll;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use FilterIterator;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -22,45 +29,45 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
* Poll Votes Filter Iterator
|
||||
* @note When we require PHP 5.4+ this can just be replaced with a CallbackFilterIterator
|
||||
*/
|
||||
class _Iterator extends \FilterIterator
|
||||
class Iterator extends FilterIterator
|
||||
{
|
||||
/**
|
||||
* @brief Question
|
||||
*/
|
||||
protected $question;
|
||||
protected ?int $question = NULL;
|
||||
|
||||
/**
|
||||
* @brief Option
|
||||
*/
|
||||
protected $option;
|
||||
protected ?int $option = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Patterns\ActiveRecordIterator $iterator Iterator
|
||||
* @param ActiveRecordIterator $iterator Iterator
|
||||
* @param int|null $question Question
|
||||
* @param int|null $option Option
|
||||
* @param int|null $option Option
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Patterns\ActiveRecordIterator $iterator, $question=NULL, $option=NULL )
|
||||
public function __construct(ActiveRecordIterator $iterator, int $question=NULL, int $option=NULL )
|
||||
{
|
||||
$this->question = $question;
|
||||
$this->option = $option;
|
||||
return parent::__construct( $iterator );
|
||||
parent::__construct( $iterator );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this rule apply?
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function accept()
|
||||
public function accept() : bool
|
||||
{
|
||||
$row = $this->getInnerIterator()->current();
|
||||
|
||||
if ( \is_array( $row->member_choices[ $this->question ] ) )
|
||||
if ( is_array( $row->member_choices[ $this->question ] ) )
|
||||
{
|
||||
return (bool) \in_array( $this->option, $row->member_choices[ $this->question ] );
|
||||
return in_array( $this->option, $row->member_choices[ $this->question ] );
|
||||
}
|
||||
|
||||
return $row->member_choices[ $this->question ] == $this->option;
|
||||
|
||||
+165
-133
@@ -11,60 +11,81 @@
|
||||
namespace IPS;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Date;
|
||||
use IPS\Patterns\ActiveRecord;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Poll\Iterator;
|
||||
use IPS\Poll\Question;
|
||||
use IPS\Poll\Vote;
|
||||
use IPS\Text\Parser;
|
||||
use OutOfRangeException;
|
||||
use SplObserver;
|
||||
use SplSubject;
|
||||
use Throwable;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll Model
|
||||
*/
|
||||
class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
class Poll extends ActiveRecord implements SplSubject
|
||||
{
|
||||
/**
|
||||
* @brief Database Table
|
||||
*/
|
||||
public static $databaseTable = 'core_polls';
|
||||
public static ?string $databaseTable = 'core_polls';
|
||||
|
||||
/**
|
||||
* @brief Database ID Column
|
||||
*/
|
||||
public static $databaseColumnId = 'pid';
|
||||
public static string $databaseColumnId = 'pid';
|
||||
|
||||
/**
|
||||
* @brief Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
protected static array $multitons;
|
||||
|
||||
/**
|
||||
* @brief Display template
|
||||
*/
|
||||
public $displayTemplate;
|
||||
public mixed $displayTemplate = NULL;
|
||||
|
||||
/**
|
||||
* @brief URL to use instead of \IPS\Request::i()->url()
|
||||
*/
|
||||
public $url;
|
||||
public mixed $url = NULL;
|
||||
|
||||
/**
|
||||
* Set Default Values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValues()
|
||||
public function setDefaultValues() : void
|
||||
{
|
||||
$this->start_date = new \IPS\DateTime;
|
||||
$this->start_date = new DateTime;
|
||||
$this->poll_close_date = -1;
|
||||
$this->choices = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set start date
|
||||
*
|
||||
* @param \IPS\DateTime $value Value
|
||||
* @param DateTime $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set_start_date( \IPS\DateTime $value )
|
||||
public function set_start_date( DateTime $value ) : void
|
||||
{
|
||||
$this->_data['start_date'] = $value->getTimestamp();
|
||||
}
|
||||
@@ -72,31 +93,31 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Get start date
|
||||
*
|
||||
* @return \IPS\DateTime
|
||||
* @return DateTime
|
||||
*/
|
||||
public function get_start_date()
|
||||
public function get_start_date(): DateTime
|
||||
{
|
||||
return \IPS\DateTime::ts( $this->_data['start_date'] );
|
||||
return DateTime::ts( $this->_data['start_date'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll load - We do this so that we can close the poll in realtime when it's viewed.
|
||||
*
|
||||
* @see \IPS\Db::build
|
||||
* @param int|string $id ID
|
||||
* @param string $idField The database column that the $id parameter pertains to (NULL will use static::$databaseColumnId)
|
||||
* @see Db::build
|
||||
* @param int|string|null $id ID
|
||||
* @param string|null $idField The database column that the $id parameter pertains to (NULL will use static::$databaseColumnId)
|
||||
* @param mixed $extraWhereClause Additional where clause(s) (see \IPS\Db::build for details) - if used will cause multiton store to be skipped and a query always ran
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \OutOfRangeException
|
||||
* @return static|ActiveRecord
|
||||
* @throws InvalidArgumentException
|
||||
* @throws OutOfRangeException
|
||||
*/
|
||||
public static function load( $id, $idField=NULL, $extraWhereClause=NULL )
|
||||
public static function load( int|string|null $id, string $idField=NULL, mixed $extraWhereClause=NULL ): ActiveRecord|static
|
||||
{
|
||||
$poll = parent::load( $id, $idField, $extraWhereClause );
|
||||
|
||||
if( $poll->poll_close_date instanceof \IPS\DateTime )
|
||||
if( $poll->poll_close_date instanceof DateTime)
|
||||
{
|
||||
if( !$poll->poll_closed and $poll->poll_close_date < \IPS\DateTime::create() )
|
||||
if( !$poll->poll_closed and $poll->poll_close_date < DateTime::create() )
|
||||
{
|
||||
$poll->poll_closed = 1;
|
||||
$poll->save();
|
||||
@@ -112,7 +133,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
* @param array $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set_choices( array $value )
|
||||
public function set_choices( array $value ) : void
|
||||
{
|
||||
$this->_data['choices'] = json_encode( $value );
|
||||
}
|
||||
@@ -120,16 +141,20 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* @brief Poll close date \IPS\DateTime object
|
||||
*/
|
||||
protected $_pollCloseDateObject = null;
|
||||
protected ?DateTime $_pollCloseDateObject = null;
|
||||
|
||||
/**
|
||||
* Get Poll Close Date
|
||||
*
|
||||
* @return \IPS\DateTime|int
|
||||
* @return DateTime|int|null
|
||||
*/
|
||||
public function get_poll_close_date() : \IPS\DateTime|int
|
||||
public function get_poll_close_date() : DateTime|int|null
|
||||
{
|
||||
if( $this->_pollCloseDateObject instanceof \IPS\DateTime )
|
||||
if( !isset( $this->_data['poll_close_date'] ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if( $this->_pollCloseDateObject instanceof DateTime)
|
||||
{
|
||||
return $this->_pollCloseDateObject;
|
||||
}
|
||||
@@ -138,18 +163,18 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
return $this->_data['poll_close_date'];
|
||||
}
|
||||
|
||||
return $this->_pollCloseDateObject = \IPS\DateTime::ts( $this->_data['poll_close_date'] );
|
||||
return $this->_pollCloseDateObject = DateTime::ts( $this->_data['poll_close_date'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Poll Close Date
|
||||
*
|
||||
* @param \IPS\DateTime|int $date
|
||||
* @param int|DateTime $date
|
||||
* @return void
|
||||
*/
|
||||
public function set_poll_close_date( $date )
|
||||
public function set_poll_close_date( int|DateTime $date ) : void
|
||||
{
|
||||
if( $date instanceof \IPS\DateTime )
|
||||
if( $date instanceof DateTime)
|
||||
{
|
||||
$this->changed['poll_close_date'] = $this->_data['poll_close_date'] = $date->getTimestamp();
|
||||
$this->_pollCloseDateObject = $date;
|
||||
@@ -165,7 +190,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_choices()
|
||||
public function get_choices(): array
|
||||
{
|
||||
return json_decode( $this->_data['choices'], TRUE );
|
||||
}
|
||||
@@ -173,21 +198,21 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Get author
|
||||
*
|
||||
* @return \IPS\Member
|
||||
* @return Member
|
||||
*/
|
||||
public function author()
|
||||
public function author(): Member
|
||||
{
|
||||
return \IPS\Member::load( $this->starter_id );
|
||||
return Member::load( $this->starter_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Choices
|
||||
*
|
||||
* @param array $data Values from form
|
||||
* @param bool $allowPollOnly Allow poll-only?
|
||||
* @param array $data Values from form
|
||||
* @param bool $allowPollOnly Allow poll-only?
|
||||
* @return void
|
||||
*/
|
||||
public function setDataFromForm( $data, $allowPollOnly )
|
||||
public function setDataFromForm( array $data, bool $allowPollOnly ) : void
|
||||
{
|
||||
if ( $data['title'] )
|
||||
{
|
||||
@@ -201,8 +226,8 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
$this->poll_question = $firstQuestion['title'];
|
||||
}
|
||||
|
||||
$this->poll_only = ( \IPS\Settings::i()->ipb_poll_only and $allowPollOnly and isset( $data['poll_only'] ) );
|
||||
$this->poll_view_voters = ( \IPS\Settings::i()->poll_allow_public and isset( $data['public'] ) );
|
||||
$this->poll_only = ( Settings::i()->ipb_poll_only and $allowPollOnly and isset( $data['poll_only'] ) );
|
||||
$this->poll_view_voters = ( Settings::i()->poll_allow_public and isset( $data['public'] ) );
|
||||
|
||||
$this->votes = 0;
|
||||
$choices = array();
|
||||
@@ -220,15 +245,16 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
|
||||
foreach ( $questionData['answers'] as $answerId => $answerData )
|
||||
{
|
||||
$answerData['value'] = strip_tags( \IPS\Text\Parser::parseStatic( $answerData['value'], true, null, null, true, true, true, function( $config ) {
|
||||
$config->set( 'HTML.AllowedElements', 'a,img' );
|
||||
$answerData['value'] = strip_tags( Parser::parseStatic( $answerData['value'], null, null, true, true, function ( $config )
|
||||
{
|
||||
$config->set( 'HTML.AllowedElements', 'a,img' );
|
||||
} ), '<a><img>' );
|
||||
|
||||
/* AllowedElements strips <___base_url___> */
|
||||
$answerData['value'] = preg_replace( '#(\s+?src=[\'"])___base_url___/#', '\1<___base_url___>/', $answerData['value'] );
|
||||
$answerData['value'] = preg_replace( '#(\s+?data-src=[\'"])___base_url___/#', '\1<___base_url___>/', $answerData['value'] );
|
||||
|
||||
$count = isset( $existing[ $k ]['votes'][ $answerId ] ) ? $existing[ $k ]['votes'][ $answerId ] : 0;
|
||||
$count = $existing[$k]['votes'][$answerId] ?? 0;
|
||||
if ( trim( $answerData['value'] ) !== "" )
|
||||
{
|
||||
$choices[ $k ]['choice'][ $answerId ] = $answerData['value'];
|
||||
@@ -245,9 +271,9 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
{
|
||||
try
|
||||
{
|
||||
$timezone = $this->options['timezone'] ?: ( \IPS\Member::loggedIn()->timezone ? new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) : NULL );
|
||||
$timezone = $this->options['timezone'] ?: ( Member::loggedIn()->timezone ? new DateTimeZone( Member::loggedIn()->timezone ) : NULL );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
$timezone = NULL;
|
||||
}
|
||||
@@ -258,18 +284,18 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
$time = ' ' . $data['poll_close_time'];
|
||||
}
|
||||
|
||||
$closeDate = new \IPS\DateTime( \IPS\Helpers\Form\Date::_convertDateFormat( $data['poll_close_date'] ) . $time, $timezone );
|
||||
$closeDate = new DateTime( Date::_convertDateFormat( $data['poll_close_date'] ) . $time, $timezone );
|
||||
|
||||
/* Moderator Log */
|
||||
if( $this->poll_close_date instanceof \IPS\DateTime AND $closeDate != $this->poll_close_date )
|
||||
if( $this->poll_close_date instanceof DateTime AND $closeDate != $this->poll_close_date )
|
||||
{
|
||||
\IPS\Session::i()->modLog( 'modlog__poll_autoclose', array( $this->pid => FALSE, $closeDate->rfc1123() => FALSE) );
|
||||
Session::i()->modLog( 'modlog__poll_autoclose', array( $this->pid => FALSE, $closeDate->rfc1123() => FALSE) );
|
||||
}
|
||||
|
||||
$this->poll_close_date = $closeDate;
|
||||
|
||||
/* Close date is in the past, make sure the poll is closed */
|
||||
if( $closeDate < \IPS\DateTime::create() )
|
||||
if( $closeDate < DateTime::create() )
|
||||
{
|
||||
$this->poll_closed = 1;
|
||||
}
|
||||
@@ -287,12 +313,12 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Member can close poll?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member Member or NULL for currently logged in member
|
||||
* @return void
|
||||
* @param Member|NULL $member Member or NULL for currently logged in member
|
||||
* @return bool
|
||||
*/
|
||||
public function canClose( \IPS\Member $member = NULL )
|
||||
public function canClose( Member $member = NULL ) : bool
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
if( !$member->member_id )
|
||||
{
|
||||
@@ -315,12 +341,12 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Member can vote?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member Member or NULL for currently logged in member
|
||||
* @return void
|
||||
* @param Member|NULL $member Member or NULL for currently logged in member
|
||||
* @return bool
|
||||
*/
|
||||
public function canVote( \IPS\Member $member = NULL )
|
||||
public function canVote( Member $member = NULL ) : bool
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
@@ -332,12 +358,12 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !\IPS\Settings::i()->allow_creator_vote and $member == $this->author() )
|
||||
if ( !Settings::i()->allow_creator_vote and $member === $this->author() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !\IPS\Settings::i()->poll_allow_vdelete and $this->getVote( $member ) )
|
||||
if ( !Settings::i()->poll_allow_vdelete and $this->getVote( $member ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -353,24 +379,25 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Member can see voters?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member Member or NULL for currently logged in member
|
||||
* @return void
|
||||
* @param Member|NULL $member Member or NULL for currently logged in member
|
||||
* @return bool
|
||||
*/
|
||||
public function canSeeVoters( \IPS\Member $member = NULL )
|
||||
public function canSeeVoters( Member $member = NULL ): bool
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
return $member->modPermission('can_see_poll_voters') or ( \IPS\Settings::i()->poll_allow_public and $this->poll_view_voters );
|
||||
$member = $member ?: Member::loggedIn();
|
||||
return $member->modPermission('can_see_poll_voters') or ( Settings::i()->poll_allow_public and $this->poll_view_voters );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Vote
|
||||
*
|
||||
* @param \IPS\Poll\Vote $vote Vote
|
||||
* @return void
|
||||
* @param Vote $vote Vote
|
||||
* @param Member|null $member
|
||||
* @return void
|
||||
*/
|
||||
public function addVote( \IPS\Poll\Vote $vote, \IPS\Member $member = NULL )
|
||||
public function addVote( Vote $vote, Member $member = NULL ) : void
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
/* Delete existing vote */
|
||||
if ( $existingVote = $this->getVote( $member ) )
|
||||
@@ -395,7 +422,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
$pollChoices = $this->choices;
|
||||
foreach ( $vote->member_choices as $key => $value )
|
||||
{
|
||||
if ( \is_array( $value ) )
|
||||
if ( is_array( $value ) )
|
||||
{
|
||||
foreach ( $value as $k => $v )
|
||||
{
|
||||
@@ -427,27 +454,27 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
* @note This method does not call save()...be sure you do that yourself
|
||||
* @return void
|
||||
*/
|
||||
public function recountVotes()
|
||||
public function recountVotes() : void
|
||||
{
|
||||
/* Reset the cached count */
|
||||
$this->votes = \IPS\Db::i()->select( 'COUNT(*)', 'core_voters', array( 'poll=?', $this->pid ) )->first();
|
||||
$this->votes = Db::i()->select( 'COUNT(*)', 'core_voters', array( 'poll=?', $this->pid ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Votes
|
||||
*
|
||||
* @param int|NULL $question If you only want to retreive votes where users voted a particular answer for a particular question, provide the question ID
|
||||
* @param int|NULL $option If you only want to retreive votes where users voted a particular answer for a particular question, provide the option ID
|
||||
* @return \IPS\Patterns\ActiveRecordIterator
|
||||
* @param int|null $question If you only want to retreive votes where users voted a particular answer for a particular question, provide the question ID
|
||||
* @param int|null $option If you only want to retreive votes where users voted a particular answer for a particular question, provide the option ID
|
||||
* @return ActiveRecordIterator|Iterator
|
||||
*/
|
||||
public function getVotes( $question=NULL, $option=NULL )
|
||||
public function getVotes( int $question=NULL, int $option=NULL ): ActiveRecordIterator|Iterator
|
||||
{
|
||||
$iterator = \IPS\Db::i()->select( '*', 'core_voters', array( 'poll=?', $this->pid ) );
|
||||
$iterator = new \IPS\Patterns\ActiveRecordIterator( $iterator, 'IPS\Poll\Vote' );
|
||||
$iterator = Db::i()->select( '*', 'core_voters', array( 'poll=?', $this->pid ) );
|
||||
$iterator = new ActiveRecordIterator( $iterator, 'IPS\Poll\Vote' );
|
||||
|
||||
if ( $question !== NULL )
|
||||
{
|
||||
$iterator = new \IPS\Poll\Iterator( $iterator, $question, $option );
|
||||
$iterator = new Iterator( $iterator, $question, $option );
|
||||
}
|
||||
|
||||
return $iterator;
|
||||
@@ -456,22 +483,22 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* @brief Vote Cache
|
||||
*/
|
||||
protected $_voteCache = array();
|
||||
protected array $_voteCache = array();
|
||||
|
||||
/**
|
||||
* Get Vote
|
||||
*
|
||||
* @param \IPS\Member $member Member
|
||||
* @return \IPS\Poll\Vote|NULL
|
||||
* @param Member|null $member Member
|
||||
* @return Vote|NULL
|
||||
*/
|
||||
public function getVote( \IPS\Member $member = NULL )
|
||||
public function getVote( Member $member = NULL ): ?Vote
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
try
|
||||
{
|
||||
if ( !isset( $this->_voteCache[ $member->member_id ] ) )
|
||||
{
|
||||
$this->_voteCache[ $member->member_id ] = \IPS\Poll\Vote::load( $member->member_id, 'member_id', array( 'poll=?', $this->pid ) );
|
||||
$this->_voteCache[ $member->member_id ] = Vote::load( $member->member_id, 'member_id', array( 'poll=?', $this->pid ) );
|
||||
}
|
||||
|
||||
if ( $this->_voteCache[ $member->member_id ] === FALSE )
|
||||
@@ -481,7 +508,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
|
||||
return $this->_voteCache[ $member->member_id ];
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
$this->_voteCache[ $member->member_id ] = FALSE;
|
||||
return NULL;
|
||||
@@ -498,7 +525,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
try
|
||||
{
|
||||
/* Pre 4.x data can be bad */
|
||||
if ( !\is_array( $this->choices ) || !\count( $this->choices ) )
|
||||
if ( !is_array( $this->choices ) || !count( $this->choices ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
@@ -513,29 +540,27 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
|
||||
if ( ! $this->displayTemplate )
|
||||
{
|
||||
$this->displayTemplate = array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' ), 'poll' );
|
||||
$this->displayTemplate = array( Theme::i()->getTemplate( 'global', 'core', 'global' ), 'poll' );
|
||||
}
|
||||
|
||||
$template = $this->displayTemplate;
|
||||
$output = $template( $this, ( $this->url ?: \IPS\Request::i()->url() ) );
|
||||
$output = $template( $this, ( $this->url ?: Request::i()->url() ) );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() && \IPS\Request::i()->fetchPoll )
|
||||
if( Request::i()->isAjax() && Request::i()->fetchPoll )
|
||||
{
|
||||
/* If a vote was submitted but we're returning HTML, that means there was an error (probably a choice not selected for
|
||||
a question) so we return a 500 error code to make the form submit properly rather than showing "Your vote has been saved" */
|
||||
\IPS\Output::i()->sendOutput( $output, ( $this->buildForm() and $this->formSaved === FALSE and ! isset( \IPS\Request::i()->viewResults ) ) ? 500 : 200, 'text/html' );
|
||||
Output::i()->sendOutput( $output, ( $this->buildForm() and $this->formSaved === FALSE and ! isset( Request::i()->viewResults ) ) ? 500 : 200 );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception | Throwable $e )
|
||||
{
|
||||
\IPS\IPS::exceptionHandler( $e );
|
||||
}
|
||||
catch ( \Throwable $e )
|
||||
{
|
||||
\IPS\IPS::exceptionHandler( $e );
|
||||
IPS::exceptionHandler( $e );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -543,24 +568,31 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function canViewResults()
|
||||
public function canViewResults(): bool
|
||||
{
|
||||
if ( \IPS\Settings::i()->allow_result_view )
|
||||
/* If the poll is closed, check the group permissions.
|
||||
0 = Never
|
||||
1 = Always
|
||||
2 = When poll is closed */
|
||||
if( $this->poll_closed )
|
||||
{
|
||||
return TRUE;
|
||||
return ( Member::loggedIn()->group['g_poll_results'] > 0 );
|
||||
}
|
||||
else if( $this->poll_closed )
|
||||
elseif( Member::loggedIn()->group['g_poll_results'] == 1 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if ( isset( \IPS\Request::i()->nullVote ) and \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
if ( ! $this->getVote() )
|
||||
if ( Settings::i()->allow_result_view )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
$this->addVote( \IPS\Poll\Vote::fromForm( NULL ) );
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
else if ( isset( Request::i()->nullVote ) and Member::loggedIn()->member_id )
|
||||
{
|
||||
if ( ! $this->getVote() )
|
||||
{
|
||||
Session::i()->csrfCheck();
|
||||
$this->addVote( Vote::fromForm( NULL ) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,21 +602,21 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* @brief Flag if the form has been saved so we don't resave votes
|
||||
*/
|
||||
protected $formSaved = FALSE;
|
||||
|
||||
protected bool $formSaved = FALSE;
|
||||
|
||||
/**
|
||||
* Build Form
|
||||
*
|
||||
* @return \IPS\Helpers\Form
|
||||
* @return Form|string
|
||||
*/
|
||||
public function buildForm()
|
||||
public function buildForm(): Form|string
|
||||
{
|
||||
if ( !$this->canVote() )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form('poll', 'save_vote');
|
||||
$form = new Form('poll', 'save_vote');
|
||||
foreach ( $this->choices as $k => $data )
|
||||
{
|
||||
$class = ( isset( $data['multi'] ) AND $data['multi'] ) ? 'IPS\Helpers\Form\CheckboxSet' : 'IPS\Helpers\Form\Radio';
|
||||
@@ -597,7 +629,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
if ( $values = $form->values() AND !$this->formSaved )
|
||||
{
|
||||
$this->formSaved = TRUE;
|
||||
$this->addVote( \IPS\Poll\Vote::fromForm( $values ) );
|
||||
$this->addVote( Vote::fromForm( $values ) );
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -610,15 +642,15 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* @brief Observers
|
||||
*/
|
||||
protected $observers = array();
|
||||
protected array $observers = array();
|
||||
|
||||
/**
|
||||
* Attach Observer
|
||||
*
|
||||
* @param \SplObserver $observer
|
||||
* @param SplObserver $observer
|
||||
* @return void
|
||||
*/
|
||||
public function attach( \SplObserver $observer )
|
||||
public function attach( SplObserver $observer ) : void
|
||||
{
|
||||
$this->observers[] = $observer;
|
||||
}
|
||||
@@ -626,10 +658,10 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Attach Observer
|
||||
*
|
||||
* @param \SplObserver $observer
|
||||
* @param SplObserver $observer
|
||||
* @return void
|
||||
*/
|
||||
public function detach( \SplObserver $observer )
|
||||
public function detach( SplObserver $observer ) : void
|
||||
{
|
||||
foreach ( $this->observers as $k => $v )
|
||||
{
|
||||
@@ -645,7 +677,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function notify()
|
||||
public function notify() : void
|
||||
{
|
||||
foreach ( $this->observers as $k => $v )
|
||||
{
|
||||
@@ -656,7 +688,7 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @param Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @return array
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string title Title
|
||||
@@ -667,12 +699,12 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
* @apiresponse int votes Number of votes
|
||||
* @apiresponse [\IPS\Poll\Question] questions The questions
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
public function apiOutput( Member $authorizedMember = NULL ): array
|
||||
{
|
||||
$questions = array();
|
||||
foreach ( $this->choices as $choice )
|
||||
{
|
||||
$questions[] = ( new \IPS\Poll\Question( $choice ) )->apiOutput( $authorizedMember );
|
||||
$questions[] = ( new Question( $choice ) )->apiOutput( $authorizedMember );
|
||||
}
|
||||
|
||||
return array(
|
||||
@@ -680,8 +712,8 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
'title' => $this->poll_question,
|
||||
'startDate' => $this->start_date->rfc3339(),
|
||||
'closed' => (bool) $this->poll_closed,
|
||||
'closedDate' => ( ( $this->poll_closed AND $this->poll_close_date instanceof \IPS\DateTime ) ? $this->poll_close_date->rfc3339() : null ),
|
||||
'public' => (bool) $this->poll_view_voters,
|
||||
'closedDate' => ( ( $this->poll_closed AND $this->poll_close_date instanceof DateTime) ? $this->poll_close_date->rfc3339() : null ),
|
||||
'public' => $this->poll_view_voters,
|
||||
'votes' => $this->votes,
|
||||
'questions' => $questions
|
||||
);
|
||||
@@ -690,9 +722,9 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* Save Changed Columns
|
||||
*
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
public function save(): void
|
||||
{
|
||||
$new = FALSE;
|
||||
if ( $this->_new )
|
||||
@@ -711,13 +743,13 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete(): void
|
||||
{
|
||||
parent::delete();
|
||||
|
||||
/* Delete records from voters table */
|
||||
\IPS\Db::i()->delete( 'core_voters', array( 'poll=?', $this->pid ) );
|
||||
Db::i()->delete( 'core_voters', array( 'poll=?', $this->pid ) );
|
||||
}
|
||||
}
|
||||
@@ -11,29 +11,33 @@
|
||||
namespace IPS\Poll;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll Question
|
||||
*/
|
||||
class _Question
|
||||
class Question
|
||||
{
|
||||
/**
|
||||
* @brief Data
|
||||
*/
|
||||
protected $data;
|
||||
protected array $data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $data Data
|
||||
* @param array $data Data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $data )
|
||||
public function __construct( array $data )
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
@@ -41,12 +45,12 @@ class _Question
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @param Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @return array
|
||||
* @apiresponse string question The question
|
||||
* @apiresponse object options Each of the options and how many votes they have had
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
public function apiOutput( Member $authorizedMember = NULL ): array
|
||||
{
|
||||
return array(
|
||||
'question' => $this->data['question'],
|
||||
|
||||
+39
-30
@@ -11,57 +11,66 @@
|
||||
namespace IPS\Poll;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Member;
|
||||
use IPS\Patterns\ActiveRecord;
|
||||
use IPS\Poll;
|
||||
use IPS\Request;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll Vote Model
|
||||
*/
|
||||
class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
class Vote extends ActiveRecord
|
||||
{
|
||||
/**
|
||||
* @brief Database Table
|
||||
*/
|
||||
public static $databaseTable = 'core_voters';
|
||||
public static ?string $databaseTable = 'core_voters';
|
||||
|
||||
/**
|
||||
* @brief Database ID Column
|
||||
*/
|
||||
public static $databaseColumnId = 'vid';
|
||||
public static string $databaseColumnId = 'vid';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array( 'member_id' );
|
||||
protected static array $databaseIdFields = array( 'member_id' );
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Map
|
||||
*/
|
||||
protected static $multitonMap = array();
|
||||
protected static array $multitonMap = array();
|
||||
|
||||
/**
|
||||
* @brief Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
protected static array $multitons;
|
||||
|
||||
/**
|
||||
* Create from form
|
||||
*
|
||||
* @param array|NULL $values Form values
|
||||
* @return \IPS\Poll\Vote
|
||||
* @return Vote
|
||||
*/
|
||||
public static function fromForm( $values )
|
||||
public static function fromForm( array|null $values ): Vote
|
||||
{
|
||||
$vote = new static;
|
||||
$vote->member_id = \IPS\Member::loggedIn()->member_id;
|
||||
$vote->member_id = Member::loggedIn()->member_id;
|
||||
if ( $values )
|
||||
{
|
||||
$vote->member_choices = $values;
|
||||
}
|
||||
$vote->ip_address = \IPS\Request::i()->ipAddress();
|
||||
$vote->ip_address = Request::i()->ipAddress();
|
||||
return $vote;
|
||||
}
|
||||
|
||||
@@ -70,18 +79,18 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValues()
|
||||
public function setDefaultValues() : void
|
||||
{
|
||||
$this->vote_date = new \IPS\DateTime;
|
||||
$this->vote_date = new DateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set vote date
|
||||
*
|
||||
* @param \IPS\DateTime $value Value
|
||||
* @param DateTime $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set_vote_date( \IPS\DateTime $value )
|
||||
public function set_vote_date( DateTime $value ) : void
|
||||
{
|
||||
$this->_data['vote_date'] = $value->getTimestamp();
|
||||
}
|
||||
@@ -89,11 +98,11 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
/**
|
||||
* Get vote date
|
||||
*
|
||||
* @return \IPS\DateTime
|
||||
* @return DateTime
|
||||
*/
|
||||
public function get_vote_date()
|
||||
public function get_vote_date(): DateTime
|
||||
{
|
||||
return \IPS\DateTime::ts( $this->_data['vote_date'] );
|
||||
return DateTime::ts( $this->_data['vote_date'] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +111,7 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
* @param array $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set_member_choices( array $value )
|
||||
public function set_member_choices( array $value ) : void
|
||||
{
|
||||
$this->_data['member_choices'] = json_encode( $value );
|
||||
}
|
||||
@@ -110,9 +119,9 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
/**
|
||||
* Get choices
|
||||
*
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function get_member_choices()
|
||||
public function get_member_choices(): ?array
|
||||
{
|
||||
return isset( $this->_data['member_choices'] ) ? json_decode( $this->_data['member_choices'], TRUE ) : NULL;
|
||||
}
|
||||
@@ -120,10 +129,10 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
/**
|
||||
* Set poll
|
||||
*
|
||||
* @param \IPS\Poll $value Value
|
||||
* @param Poll $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set_poll( \IPS\Poll $value )
|
||||
public function set_poll( Poll $value ) : void
|
||||
{
|
||||
$this->_data['poll'] = $value->pid;
|
||||
}
|
||||
@@ -131,19 +140,19 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
/**
|
||||
* Get poll
|
||||
*
|
||||
* @return array
|
||||
* @return Poll
|
||||
*/
|
||||
public function get_poll()
|
||||
public function get_poll(): Poll
|
||||
{
|
||||
return \IPS\Poll::load( $this->_data['poll'] );
|
||||
return Poll::load( $this->_data['poll'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Record
|
||||
*
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete(): void
|
||||
{
|
||||
if ( $this->member_choices !== NULL )
|
||||
{
|
||||
@@ -152,7 +161,7 @@ class _Vote extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
if ( isset( $choices[ $k ] ) ) // If the question has been deleted since this vote was cast, this won't be set
|
||||
{
|
||||
if ( \is_array( $v ) )
|
||||
if ( is_array( $v ) )
|
||||
{
|
||||
foreach ( $v as $key => $memberValues )
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user