Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

@@ -0,0 +1,53 @@
<?php
/**
* @brief Account Settings Extension
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\AccountSettings;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Extensions\AccountSettingsAbstract;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* AccountSettings Extension
*/
class {class} extends AccountSettingsAbstract
{
/**
* @var string
*/
public static string $icon = 'cog';
/**
* Return the key for the tab, or NULL if it should not be displayed
*
* @return string|null
*/
public function getTab() : string|null
{
return '{tabKey}';
}
/**
* Return the content for the main tab
*
* @return string
*/
public function getContent() : string
{
return '';
}
}
@@ -11,25 +11,32 @@
namespace IPS\{app}\extensions\core\AchievementAction;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\Achievements\Actions\AchievementActionAbstract;
use IPS\core\Achievements\Rule;
use IPS\Http\Url;
use IPS\Member as MemberClass;
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;
}
/**
* Achievement Action Extension
*/
class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction // NOTE: Other classes exist to provided bases for common situations, like where node-based filters will be required
class {class} extends AchievementActionAbstract // NOTE: Other classes exist to provided bases for common situations, like where node-based filters will be required
{
/**
* Get filter form elements
*
* @param array|NULL $filters Current filter values (if editing)
* @param \IPS\Http\Url $url The URL the form is being shown on
* @param Url $url The URL the form is being shown on
* @return array
*/
public function filters( ?array $filters, \IPS\Http\Url $url ): array
public function filters( ?array $filters, Url $url ): array
{
return [];
}
@@ -52,12 +59,12 @@ class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction
* calls that BEFORE making its change in the database (or there is read/write separation), you will need to add
* 1 to the value being considered for milestones
*
* @param \IPS\Member $subject The subject member
* @param MemberClass $subject The subject member
* @param array $filters The value returned by formatFilterValues()
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
* @return bool
*/
public function filtersMatch( \IPS\Member $subject, array $filters, $extra = NULL ): bool
public function filtersMatch( MemberClass $subject, array $filters, mixed $extra = NULL ): bool
{
return TRUE;
}
@@ -80,24 +87,24 @@ class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction
/**
* Get the "other" people we need to award =stuff to
*
* @param array|NULL $filters Current filter values
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
* @param array|NULL $filters Current filter values
* @return array
*/
// public function awardOther(?array $filters, $extra = NULL ): array
// public function awardOther( mixed $extra = NULL, ?array $filters = NULL ): array
// {
// return [ \IPS\Member::loggedIn() ];
// return [ MemberClass::loggedIn() ];
// }
/**
* Get identifier to prevent the member being awarded points for the same action twice
* Must be unique within within of this domain, must not exceed 32 chars.
*
* @param \IPS\Member $subject The subject member
* @param MemberClass $subject The subject member
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
* @return string
*/
public function identifier( \IPS\Member $subject, $extra = NULL ): string
public function identifier( MemberClass $subject, mixed $extra = NULL ): string
{
return (string) $extra->id;
}
@@ -117,10 +124,10 @@ class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction
/**
* Get "description" for rule
*
* @param \IPS\core\Achievements\Rule $rule The rule
* @param Rule $rule The rule
* @return string|NULL
*/
public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string
public function ruleDescription( Rule $rule ): ?string
{
return "{class}";
}
@@ -130,7 +137,7 @@ class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction
*
* @return array
*/
static public function rebuildData()
static public function rebuildData(): array
{
// This method returns an array of tables that this extension uses to award achievements, so for example
// the follow extension uses 'core_follow'.
@@ -139,12 +146,12 @@ class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction
// Where shouldn't attempt to limit based on filters or milestones, but just remove data that you don't need to
// look at, such as banned members, archived items and so on. You can return an empty array if you do not need
// a where statement.
//return [ [
return [ [
// 'table' => 'table_name',
// 'pkey' => 'field_id',
// 'date' => 'field_date',
// 'where' => [ [ 'banned != 1' ] ],
//] ];
] ];
}
/**
@@ -154,11 +161,11 @@ class _{class} extends \IPS\core\Achievements\Actions\AbstractAchievementAction
* @param array $data Data collected when starting rebuild [table, pkey...]
* @return void
*/
public static function rebuildRow( $row, $data )
public static function rebuildRow( array $row, array $data ) : void
{
// This method runs the achievementAction on the table row from the table (or tables) you specified in rebuildData()
// You are welcome to load any classes, etc you need here.
//IPS\Member::loggedIn()->achievementAction( '{app}', '{class}', $row['field_id'] ), \IPS\DateTime::ts( $row['field_date'] ) );
//MemberClass::loggedIn()->achievementAction( '{app}', '{class}', $row['field_id'] ), \IPS\DateTime::ts( $row['field_date'] ) );
}
}
@@ -11,38 +11,44 @@
namespace IPS\{app}\extensions\core\AdminNotifications;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\AdminNotification;
use IPS\Http\Url;
use IPS\Member as MemberClass;
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;
}
/**
* ACP Notification Extension
*/
class _{class} extends \IPS\core\AdminNotification
class {class} extends AdminNotification
{
/**
* @brief Identifier for what to group this notification type with on the settings form
*/
public static $group = 'other';
public static string $group = '{group}';
/**
* @brief Priority 1-5 (1 being highest) for this group compared to others
*/
public static $groupPriority = 3;
public static int $groupPriority = 3;
/**
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
*/
public static $itemPriority = 1;
public static int $itemPriority = {priority};
/**
* Title for settings
*
* @return string
*/
public static function settingsTitle()
public static function settingsTitle(): string
{
return 'acp_notification_{class}';
}
@@ -50,10 +56,10 @@ class _{class} extends \IPS\core\AdminNotification
/**
* Can a member access this type of notification?
*
* @param \IPS\Member $member The member
* @param MemberClass $member The member
* @return bool
*/
public static function permissionCheck( \IPS\Member $member ): bool
public static function permissionCheck( MemberClass $member ): bool
{
return true;// $member->hasAcpRestriction( ... );
}
@@ -61,9 +67,9 @@ class _{class} extends \IPS\core\AdminNotification
/**
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
*
* @return string
* @return bool
*/
public static function mayBeOptional()
public static function mayBeOptional(): bool
{
return FALSE;
}
@@ -91,9 +97,9 @@ class _{class} extends \IPS\core\AdminNotification
/**
* Notification Body (full HTML, must be escaped where necessary)
*
* @return string
* @return string|null
*/
public function body(): string
public function body(): ?string
{
return "Body";
}
@@ -105,7 +111,7 @@ class _{class} extends \IPS\core\AdminNotification
*/
public function severity(): string
{
return static::SEVERITY_NORMAL;
return {severity};
}
/**
@@ -118,23 +124,13 @@ class _{class} extends \IPS\core\AdminNotification
return static::DISMISSIBLE_TEMPORARY;
}
/**
* Style
*
* @return bool
*/
public function style(): string
{
return static::STYLE_INFORMATION;
}
/**
* Quick link from popup menu
*
* @return \IPS\Http\Url
* @return Url
*/
public function link(): \IPS\Http\Url
public function link(): Url
{
return parent::link(); // \IPS\Http\Url::internal( '...' );
return parent::link(); // Url::internal( '...' );
}
}
@@ -12,16 +12,21 @@
namespace IPS\{app}\extensions\core\AdvertisementLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\AdvertisementLocationsAbstract;
use function defined;
use IPS\core\Advertisement as AdvertisementClass;
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;
}
/**
* Advertisement locations extension
*/
class _{class}
class {class} extends AdvertisementLocationsAbstract
{
/**
* Get the locations and the additional settings
@@ -29,7 +34,7 @@ class _{class}
* @param array $settings Current setting values
* @return array Array with two elements: 'locations' which should have keys as the location keys and values as the fields to toggle, and 'settings' which are additional fields to add to the form
*/
public function getSettings( $settings ): array
public function getSettings( array $settings ): array
{
return array( 'locations' => array(), 'settings' => array() );
}
@@ -40,8 +45,20 @@ class _{class}
* @param array $values Values from the form submission
* @return array Array of setting key => value to store
*/
public function parseSettings( $values ): array
public function parseSettings( array $values ): array
{
return array();
}
/**
* Check if the advertisement can be displayed, based on settings
*
* @param AdvertisementClass $advertisement
* @param string $location
* @return bool
*/
public function canShow( AdvertisementClass $advertisement, string $location ) : bool
{
return TRUE;
}
}
@@ -11,30 +11,36 @@
namespace IPS\{app}\extensions\core\Announcements;
use IPS\core\Announcements\Announcement as AnnouncementClass;
use IPS\Extensions\AnnouncementsAbstract;
use IPS\Helpers\Form\FormAbstract;
use IPS\Helpers\Form\Node;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Announcements Extension
*/
class _{class}
class {class} extends AnnouncementsAbstract
{
public static $idField = "id";
public static string $idField = "id";
public static $controllers = array();
public static array $controllers = array();
/**
* Get Setting Field
*
* @param \IPS\core\Announcements\Announcement $announcement
* @return \IPS\Helpers\Form\FormAbstract Form element
* @param AnnouncementClass|null $announcement
* @return FormAbstract Form element
*/
public function getSettingField( ?\IPS\core\Announcements\Announcement $announcement ): \IPS\Helpers\Form\FormAbstract
public function getSettingField( ?AnnouncementClass $announcement ): FormAbstract
{
return new \IPS\Helpers\Form\Node( 'announce_download_categories', ( $announcement ) ? explode( ",", $announcement->ids ) : NULL, FALSE, array( 'class' => 'IPS\downloads\Category', 'zeroVal' => 'any', 'multiple' => TRUE ), NULL, NULL, NULL, 'announce_download_categories' );
return new Node( 'announce_download_categories', ( $announcement ) ? explode( ",", $announcement->ids ) : NULL, FALSE, array( 'class' => 'IPS\downloads\Category', 'zeroVal' => 'any', 'multiple' => TRUE ), NULL, NULL, NULL, 'announce_download_categories' );
}
}
@@ -0,0 +1,55 @@
<?php
/**
* @brief Approval reason plugin
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\ApprovalReason;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\core\Approval as ApprovalClass;
use IPS\Extensions\ApprovalReasonAbstract;
use RuntimeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Approval reason plugin
*/
class {class} extends ApprovalReasonAbstract
{
/**
* Reason Key
*
* @return string
*/
public function reasonKey(): string
{
return '';
}
/**
* Parse Reason
*
* @param ApprovalClass $approval Approval row
* @return array
*/
public function parseReason( ApprovalClass $approval ): array
{
return array(
'lang' => '',
'sprintf' => array()
);
}
}
@@ -1,59 +0,0 @@
<?php
/**
* @brief BBCode Tag
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\BBCode;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* BBCode Tag
*/
class _{class}
{
/**
* Permission Check
*
* @param \IPS\Member $member The member
* @param string $area The Editor area
* @return bool
*/
public function permissionCheck( \IPS\Member $member, $area ): bool
{
return \IPS\Text\Parser::canUse( $member, 'ipsLink', $area );
}
/**
* Get Configuration
*
* @code
return array(
'tag' => 'span', // The HTML tag to use
'attributes' => array( ... ) // Key/Value pairs of attributes to use (optional) - can use {option} to get the [tag=option] value
'callback' => function( $node, $matches, $document ) // A callback to modify the DOMNode object
{
...
},
'block' => FALSE, // If this is a block-level tag (optional, default false)
'single' => FALSE, // If this is a single tag, with no content (optional, default false)
)
* @endcode
* @return array
*/
public function getConfiguration(): array
{
return array( 'tag' => 'span', 'attributes' => array( 'class' => 'example' ) );
}
}
@@ -12,24 +12,29 @@
namespace IPS\{app}\extensions\core\Build;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\BuildAbstract;
use RuntimeException;
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;
}
/**
* Build process plugin
*/
class _{class}
class {class} extends BuildAbstract
{
/**
* Build
*
* @return void
* @throws \RuntimeException
* @throws RuntimeException
*/
public function build()
public function build() : void
{
}
@@ -38,7 +43,7 @@ class _{class}
*
* @return void
*/
protected function finish()
protected function finish() : void
{
}
}
@@ -12,16 +12,21 @@
namespace IPS\{app}\extensions\core\BulkMail;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\BulkMailAbstract;
use IPS\Member as MemberClass;
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;
}
/**
* Bulk Mail Extension
*/
class _{class}
class {class} extends BulkMailAbstract
{
/**
* Get tags that can be used in bulk mail
@@ -40,10 +45,10 @@ class _{class}
*
* @param string $content Bulk Mail Content (passed in case a particular tag is computationally expensive so that the extension may "sniff" for it and elect not to perform the computation if it is not used)
* @param int $type 0=All, 1=Global, 2=Member-specific
* @param NULL|\IPS\Member $member Member object if $type is 0 or 2
* @param NULL|MemberClass $member Member object if $type is 0 or 2
* @return array
*/
public function returnTagValues( string $content, int $type, ?\IPS\Member $member ): array
public function returnTagValues( string $content, int $type, ?MemberClass $member ): array
{
return array(
'{some_tag}' => 'Value',
@@ -0,0 +1,53 @@
<?php
/**
* @brief Club plugin
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\Club;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Member\Club;
use IPS\Extensions\ClubAbstract;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use RuntimeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Club Menu plugin
*/
class {class} extends ClubAbstract
{
/**
* Tabs
*
* @param \IPS\Member\Club $club The club
* @param \IPS\Node\Model $container Container
* @return array
*/
public function tabs( Club $club, ?Model $container = NULL ): array
{
return array(
'unique_id' => array(
'href' => '',
'title' => '',
'isActive' => FALSE,
'show' => FALSE
)
);
}
}
@@ -12,36 +12,46 @@
namespace IPS\{app}\extensions\core\CommunityEnhancements;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\CommunityEnhancementsAbstract;
use IPS\Helpers\Form;
use IPS\Http\Url;
use IPS\Member as MemberClass;
use IPS\Output;
use IPS\Theme;
use LogicException;
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;
}
/**
* Community Enhancement
*/
class _{class}
class {class} extends CommunityEnhancementsAbstract
{
/**
* @brief Enhancement is enabled?
*/
public $enabled = FALSE;
public bool $enabled = FALSE;
/**
* @brief IPS-provided enhancement?
*/
public $ips = FALSE;
public bool $ips = FALSE;
/**
* @brief Enhancement has configuration options?
*/
public $hasOptions = TRUE;
public bool $hasOptions = TRUE;
/**
* @brief Icon data
*/
public $icon = "";
public string $icon = "";
/**
* Constructor
@@ -50,7 +60,7 @@ class _{class}
*/
public function __construct()
{
//$this->enabled = \IPS\Settings::i()->xxxxxx;
//$this->enabled = Settings::i()->xxxxxx;
}
/**
@@ -58,9 +68,9 @@ class _{class}
*
* @return void
*/
public function edit()
public function edit() : void
{
$form = new \IPS\Helpers\Form;
$form = new Form;
//$form->add( ... );
if ( $form->values() )
{
@@ -69,24 +79,24 @@ class _{class}
$this->testSettings();
$form->saveAsSettings();
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
Output::i()->inlineMessage = MemberClass::loggedIn()->language()->addToStack('saved');
}
catch ( \LogicException $e )
catch ( LogicException $e )
{
$form->error = $e->getMessage();
}
}
\IPS\Output::i()->sidebar['actions'] = array(
Output::i()->sidebar['actions'] = array(
'help' => array(
'title' => 'help',
'icon' => 'question-circle',
'link' => \IPS\Http\Url::internal( "http://www.example.com" ),
'link' => Url::internal( "http://www.example.com" ),
'target' => '_blank'
),
);
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'enhancements__{app}_{class}', $form );
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'enhancements__{app}_{class}', $form );
}
/**
@@ -94,29 +104,26 @@ class _{class}
*
* @param $enabled bool Enable/Disable
* @return void
* @throws \LogicException
* @throws LogicException
*/
public function toggle( $enabled )
public function toggle( bool $enabled ) : void
{
if ( $enabled )
{
$this->testSettings();
}
//\IPS\Settings::i()->changeValues( array( 'xxxxxx' => $enabled ) );
//Settings::i()->changeValues( array( 'xxxxxx' => $enabled ) );
}
/**
* Test Settings
*
* @return void
* @throws \LogicException
* @throws LogicException
*/
protected function testSettings()
protected function testSettings() : void
{
if ( FALSE )
{
throw new \LogicException( 'error' );
}
throw new LogicException( 'error' );
}
}
@@ -12,28 +12,33 @@
namespace IPS\{app}\extensions\core\ContactUs;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\ContactUsAbstract;
use IPS\Helpers\Form;
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;
}
/**
* Contact Us extension
*/
class _{class}
class {class} extends ContactUsAbstract
{
/**
* Process Form
*
* @param \IPS\Helpers\Form $form The form
* @param Form $form The form
* @param array $formFields Additional Configuration Formfields
* @param array $options Type Radio Form Options
* @param array $toggles Type Radio Form Toggles
* @param array $disabled Type Radio Form Disabled Options
* @return void
*/
public function process( &$form, &$formFields, &$options, &$toggles, &$disabled )
public function process( Form &$form, array &$formFields, array &$options, array &$toggles, array &$disabled ) : void
{
}
@@ -41,10 +46,10 @@ class _{class}
/**
* Allows extensions to do something before the form is shown... e.g. add your own custom fields, or redirect the page
*
* @param \IPS\Helpers\Form $form The form
* @param Form $form The form
* @return void
*/
public function runBeforeFormOutput( &$form )
public function runBeforeFormOutput( Form $form ) : void
{
}
@@ -53,9 +58,9 @@ class _{class}
* Handle the Form
*
* @param array $values Values from form
* @return void
* @return bool
*/
public function handleForm( array $values )
public function handleForm( array $values ) : bool
{
return FALSE;
}
@@ -1,72 +0,0 @@
<?php
/**
* @brief Moderator Permissions: {class}
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\ContentModeratorPermissions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Moderator Permissions: {class}
*/
class _{class}
{
/**
* Get Permissions
*
* @param array $toggles Toggle data
* @code
return array(
'key' => 'YesNo', // Can just return a string with type
'key' => array( // Or an array for more options
'YesNo', // Type
array( ... ), // Options (as defined by type's class)
'prefix', // Prefix
'suffix', // Suffix
),
...
);
* @endcode
* @return array
*/
public function getPermissions( $toggles ): array
{
return array();
}
/**
* After change
*
* @param array $moderator The moderator
* @param array $changed Values that were changed
* @return void
*/
public function onChange( $moderator, $changed )
{
}
/**
* After change
*
* @param array $moderator The moderator
* @return void
*/
public function onDelete( $moderator )
{
}
}
@@ -12,38 +12,41 @@
namespace IPS\{app}\extensions\core\ContentRouter;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\Extensions\ContentRouterAbstract;
use IPS\Member as MemberClass;
use IPS\Member\Group;
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;
}
/**
* @brief Content Router extension: {class}
*/
class _{class}
class {class} extends ContentRouterAbstract
{
/**
* @brief Content Item Classes
*/
public $classes = array();
* @brief Can be shown in similar content
*/
public bool $similarContent = FALSE;
/**
* @brief Can be shown in similar content
*/
public $similarContent = FALSE;
/**
* Constructor
*
* @param \IPS\Member|IPS\Member\Group|NULL $memberOrGroup If checking access, the member/group to check for, or NULL to not check access
* @param MemberClass|Group|NULL $memberOrGroup If checking access, the member/group to check for, or NULL to not check access
* @return void
*/
public function __construct( $memberOrGroup = NULL )
public function __construct( MemberClass|Group|null $memberOrGroup = NULL )
{
if ( $memberOrGroup === NULL or $memberOrGroup->canAccessModule( \IPS\Application\Module::get( '{app}', '{module}', 'front' ) ) )
if ( $memberOrGroup === NULL or $memberOrGroup->canAccessModule( Module::get( '{app}', '{module}', 'front' ) ) )
{
$this->classes[] = 'IPS\{app}\{example}';
$this->classes[] = '{item}';
}
}
}
@@ -1,42 +0,0 @@
<?php
/**
* @brief Create Menu Extension : {class}
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\CreateMenu;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Create Menu Extension: {class}
*/
class _{class}
{
/**
* Get Items
*
* @return array
*/
public function getItems(): array
{
return array(
'example_key' => array(
'link' => \IPS\Http\Url::internal( '...', 'front' ),
'title' => 'example',
'flashMessage' => 'saved',
'extraData' => array( 'data-ipsDialog' => true )
)
);
}
}
@@ -0,0 +1,125 @@
<?php
/**
* @brief Custom Field Extension
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\CustomField;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\CustomField;
use IPS\Extensions\CustomFieldAbstract;
use IPS\Helpers\Form;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* CustomField Extension
*/
class {class} extends CustomFieldAbstract
{
/**
* The value that will be used for the "field type"
* This must be unique
*
* @return string
*/
public static function fieldType() : string
{
return '';
}
/**
* Language string for the title of the field type.
* Will be displayed in the "Field Type" dropdown list when
* creating a custom field
*
* @return string
*/
public static function fieldTypeTitle() : string
{
return '';
}
/**
* The class that should be called to render the field
* in a form. This class should extend FormAbstract (or an existing field)
* @see CustomField::buildHelper()
*
* @return string
*/
public static function formClass() : string
{
return '';
}
/**
* Can be overridden by individual extension implementations
* to allow for a field to be available only in certain connditions
*
* @return bool
*/
public static function isEnabled() : bool
{
return true;
}
/**
* A list of form elements that will be toggled on when this field
* type is selected
* @see CustomField::$additionalFieldToggles
*
* @return array
*/
public static function fieldTypeToggles() : array
{
return [];
}
/**
* Add fields to the field creation form
*
* @param Form $form
* @param CustomField $field The field currently being modified
* @return void
*/
public static function form( Form $form, CustomField $field ) : void
{
}
/**
* Process values from the ACP Custom Field form
*
* @param array $values
* @return array
*/
public static function formatFormValues( array $values ) : array
{
return $values;
}
/**
* Display Value
* @see CustomField::displayValue()
*
* @param CustomField $field
* @param mixed|null $value The value
* @param bool $showSensitiveInformation If TRUE, potentially sensitive data (like passwords) will be displayed - otherwise will be blanked out
* @param string|null $separator Used to separate items when displaying a field with multiple values.
* @return string|null
*/
public static function displayValue( CustomField $field, mixed $value=NULL, bool $showSensitiveInformation=FALSE, string $separator=NULL ): ?string
{
return $value;
}
}
@@ -12,16 +12,20 @@
namespace IPS\{app}\extensions\core\Dashboard;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\DashboardAbstract;
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;
}
/**
* @brief Dashboard extension: {class}
*/
class _{class}
class {class} extends DashboardAbstract
{
/**
* Can the current user view this dashboard item?
@@ -1,55 +0,0 @@
<?php
/**
* @brief DesignersMode extension: {class}
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\DesignersMode;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief DesignersMode extension: {class}
*/
class _{class}
{
/**
* Anything need building?
*
* @return bool
*/
public function toBuild()
{
}
/**
* Designer's mode on
*
* @return bool
*/
public function on( $data=NULL )
{
}
/**
* Designer's mode off
*
* @return bool
*/
public function off( $data=NULL )
{
}
}
@@ -12,36 +12,35 @@
namespace IPS\{app}\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content as ContentClass;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member as MemberClass;
use IPS\Node\Model;
use LogicException;
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;
}
/**
* Editor Extension: {class}
*/
class _{class}
class {class} extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param MemberClass $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( MemberClass $member, Editor $field ): ?bool
{
return NULL;
}
@@ -49,7 +48,7 @@ class _{class}
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param MemberClass $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -57,7 +56,7 @@ class _{class}
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE ): bool
public function attachmentPermissionCheck( MemberClass $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
/* Make sure that you add a relevant permission check to prevent attachments being accessed via ID enumeration. */
return TRUE;
@@ -69,26 +68,15 @@ class _{class}
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|ContentClass|Model|MemberClass|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( ?int $id1=NULL, ?int $id2=NULL, ?string $id3=NULL ): Model|ContentClass|Url|MemberClass|null
{
// return \IPS\Http\Url::internal( ... );
return NULL;
// return Url::internal( ... );
}
/**
* Rebuild attachment images in non-content item areas
*
* @param int|null $offset Offset to start from
* @param int|null $max Maximum to parse
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
//public function rebuildAttachmentImages( $offset, $max )
//{
//}
/**
* Rebuild content post-upgrade
*
@@ -97,15 +85,10 @@ class _{class}
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
//public function rebuildContent( $offset, $max )
//public function rebuildContent( ?int $offset, ?int $max ): int
//{
//}
/**
* @brief Store lazy loading status ( true = enabled )
*/
protected $_lazyLoadStatus = null;
/**
* Rebuild content to add or remove lazy loading
*
@@ -115,7 +98,7 @@ class _{class}
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
//public function rebuildLazyLoad( $offset, $max, $status=TRUE )
//public function rebuildLazyLoad( ?int $offset, ?int $max, bool $status=TRUE ): int
//{
//}
@@ -124,7 +107,7 @@ class _{class}
*
* @return int Total Count
*/
//public function contentCount()
//public function contentCount() : int
//{
// return \IPS\Db::i()->select( 'COUNT(*) as count', '...', "..." )->setKeyField('count')->first();
//}
@@ -12,26 +12,31 @@
namespace IPS\{app}\extensions\core\EditorMedia;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\EditorMediaAbstract;
use IPS\Member as MemberClass;
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;
}
/**
* Editor Media: {class}
*/
class _{class}
class {class} extends EditorMediaAbstract
{
/**
* Get Counts
*
* @param \IPS\Member $member The member
* @param MemberClass $member The member
* @param string $postKey The post key
* @param string|null $search The search term (or NULL for all)
* @return int
* @return array
*/
public function count( $member, $postKey, $search=NULL )
public function count( MemberClass $member, string $postKey, ?string $search=NULL ): array
{
return array();
}
@@ -39,14 +44,14 @@ class _{class}
/**
* Get Files
*
* @param \IPS\Member $member The member
* @param MemberClass $member The member
* @param string|null $search The search term (or NULL for all)
* @param string $postKey The post key
* @param int $page Page
* @param int $limit Number to get
* @return array array( 'Title' => array( 'http://www.example.com/file1.txt' => \IPS\File, 'http://www.example.com/file2.txt' => \IPS\File, ... ), ... )
*/
public function get( $member, $search, $postKey, $page, $limit ): array
public function get( MemberClass $member, ?string $search, string $postKey, int $page, int $limit ): array
{
return array();
}
@@ -12,16 +12,23 @@
namespace IPS\{app}\extensions\core\FileStorage;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Extensions\FileStorageAbstract;
use IPS\File as SystemFile;
use UnderflowException;
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;
}
/**
* File Storage Extension: {class}
*/
class _{class}
class {class} extends FileStorageAbstract
{
/**
* Count stored files
@@ -30,7 +37,7 @@ class _{class}
*/
public function count(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', '...', '...' )->first();
return Db::i()->select( 'COUNT(*)', '...', '...' )->first();
}
/**
@@ -39,22 +46,23 @@ class _{class}
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @param int $storageConfiguration New storage configuration ID
* @param int|NULL $oldConfiguration Old storage configuration ID
* @throws \UnderflowException When file record doesn't exist. Indicating there are no more files to move
* @return void|int An offset integer to use on the next cycle, or nothing
* @throws UnderflowException When file record doesn't exist. Indicating there are no more files to move
* @return void
*/
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
{
\IPS\File::get( $oldConfiguration ?: '{app}_{class}', '...' )->move( $storageConfiguration );
SystemFile::get( $oldConfiguration ?: '{app}_{class}', '...' )->move( $storageConfiguration );
}
/**
* Check if a file is valid
*
* @param string $file The file path to check
* @param SystemFile|string $file The file path to check
* @return bool
*/
public function isValidFile( $file ): bool
public function isValidFile( SystemFile|string $file ): bool
{
return FALSE;
}
/**
@@ -62,7 +70,7 @@ class _{class}
*
* @return void
*/
public function delete()
public function delete() : void
{
}
}
@@ -0,0 +1,68 @@
<?php
/**
* @brief Forms extension
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\Forms;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Extensions\FormsAbstract;
use IPS\Helpers\Form;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Forms extension
*/
class {class} extends FormsAbstract
{
/**
* Identifies the form that will be extended.
* Valid values: registration|checkout
* @see Form::availableForExtension()
* @return string
*/
public static function formType() : string
{
return '{formType}';
}
/**
* Return an array of fields that will be added to the form
* Additional parameters will be passed in depending on the form type
* registration: no additional parameters
* checkout: currently logged in member, current invoice
*
* @return array
*/
public function formElements() : array
{
return [];
}
/**
* Handle the field values on save
* Additional parameters will be passed in depending on the form type
* registration: newly created member
* checkout: currently logged in member, current invoice
*
* @param array $values
* @return void
*/
public function processFormValues( array $values ) : void
{
}
}
@@ -12,17 +12,29 @@
namespace IPS\{app}\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\FrontNavigation\FrontNavigationAbstract;
use IPS\Dispatcher;
use IPS\Http\Url;
use IPS\Member as MemberClass;
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;
}
/**
* Front Navigation Extension: {class}
*/
class _{class} extends \IPS\core\FrontNavigation\FrontNavigationAbstract
class {class} extends FrontNavigationAbstract
{
/**
* @var string Default icon
*/
public string $defaultIcon = '\f15c';
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
@@ -30,9 +42,9 @@ class _{class} extends \IPS\core\FrontNavigation\FrontNavigationAbstract
*/
public static function typeTitle(): string
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_{app}');
return MemberClass::loggedIn()->language()->addToStack('frontnavigation_{app}');
}
/**
* Can this item be used at all?
* For example, if this will link to a particular feature which has been diabled, it should
@@ -44,7 +56,7 @@ class _{class} extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
return TRUE;
}
/**
* Can the currently logged in user access the content this item links to?
*
@@ -54,7 +66,7 @@ class _{class} extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
return TRUE;
}
/**
* Get Title
*
@@ -62,19 +74,19 @@ class _{class} extends \IPS\core\FrontNavigation\FrontNavigationAbstract
*/
public function title(): string
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_{app}');
return MemberClass::loggedIn()->language()->addToStack('frontnavigation_{app}');
}
/**
* Get Link
*
* @return \IPS\Http\Url
* @return Url
*/
public function link(): \IPS\Http\Url
public function link(): Url
{
return \IPS\Http\Url::internal( "app={app}" );
return Url::internal( "app={app}" );
}
/**
* Is Active?
*
@@ -82,16 +94,16 @@ class _{class} extends \IPS\core\FrontNavigation\FrontNavigationAbstract
*/
public function active(): bool
{
return \IPS\Dispatcher::i()->application->directory === '{app}';
return Dispatcher::i()->application->directory === '{app}';
}
/**
* Children
*
* @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview)
* @return array
* @return array|null
*/
public function children( $noStore=FALSE )
public function children( bool $noStore=FALSE ): ?array
{
return NULL;
}
@@ -12,25 +12,31 @@
namespace IPS\{app}\extensions\core\GroupForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\GroupFormAbstract;
use IPS\Helpers\Form;
use IPS\Member\Group as SystemGroup;
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;
}
/**
* Admin CP Group Form
*/
class _{class}
class {class} extends GroupFormAbstract
{
/**
* Process Form
*
* @param \IPS\Helpers\Form $form The form
* @param \IPS\Member\Group $group Existing Group
* @param Form $form The form
* @param SystemGroup $group Existing Group
* @return void
*/
public function process( &$form, $group )
public function process( Form $form, SystemGroup $group ) : void
{
$form->add( new \IPS\Helpers\Form\Text( 'example' ) );
}
@@ -38,11 +44,11 @@ class _{class}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member\Group $group The group
* @param array $values Values from form
* @param SystemGroup $group The group
* @return void
*/
public function save( $values, &$group )
public function save( array $values, SystemGroup $group ) : void
{
$group->example = $values['example'];
}
@@ -50,10 +56,10 @@ class _{class}
/**
* Can this group be deleted?
*
* @param \IPS\Member\Group $group The group
* @return void
* @param SystemGroup $group The group
* @return bool
*/
public function canDelete( $group ): bool
public function canDelete( SystemGroup $group ): bool
{
return TRUE;
}
@@ -12,9 +12,13 @@
namespace IPS\{app}\extensions\core\GroupLimits;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\GroupLimitsAbstract;
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;
}
@@ -24,7 +28,7 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
* This extension is used to define which limit values "win" when a user has secondary groups defined
*
*/
class _{class}
class {class} extends GroupLimitsAbstract
{
/**
* Get group limits by priority
@@ -1,54 +0,0 @@
<?php
/**
* @brief Incoming Email Handler
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\IncomingEmail;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Incoming Email Handler
*/
class _{class}
{
/**
* Handle email
*
* @param \IPS\Email\Incoming\Email $email The email
* @return bool
*/
public function process( \IPS\Email\Incoming\Emails $email ): bool
{
if ( FALSE )
{
// Do something with the email...
/* Save attachments */
foreach ( $files as $file )
{
$attachment = $file->makeAttachment('');
\IPS\Db::i()->insert( 'core_attachments_map', array(
'attachment_id' => $attachment['attach_id'],
'location_key' => '',
'id1' => '',
'id2' => '',
) );
}
}
return FALSE; // Must return false if not processing
}
}
@@ -12,24 +12,33 @@
namespace IPS\{app}\extensions\core\IpAddresses;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Db\Select;
use IPS\Extensions\IpAddressesAbstract;
use IPS\Helpers\Table\Db as TableDb;
use IPS\Http\Url;
use IPS\Member as MemberClass;
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;
}
/**
* IP Address Lookup extension
*/
class _{class}
class {class} extends IpAddressesAbstract
{
/**
* Removes the logged IP address
*
* @param int $timestamp
* @param int $time
* @return void
*/
public function pruneIpAddresses(int $time)
public function pruneIpAddresses( int $time ) : void
{
//
}
@@ -60,20 +69,20 @@ class _{class}
* Find Records by IP
*
* @param string $ip The IP Address
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
* @return \IPS\Helpers\Table|int|null
* @param Url|null $baseUrl URL table will be displayed on or NULL to return a count
* @return string|int|null
*/
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
public function findByIp( string $ip, ?Url $baseUrl = NULL ): string|int|null
{
/* Return count */
if ( $baseUrl === NULL )
{
return \IPS\Db::i()->select( 'COUNT(*)', 'database_table_name', array( "ip_address LIKE ?", $ip ) )->first();
return Db::i()->select( 'COUNT(*)', 'database_table_name', array( "ip_address LIKE ?", $ip ) )->first();
}
/* Init Table */
// Replace database_table_name with the database table
$table = new \IPS\Helpers\Table\Db( 'database_table_name', $baseUrl, array( "ip_address LIKE ?", $ip ) );
$table = new TableDb( 'database_table_name', $baseUrl, array( "ip_address LIKE ?", $ip ) );
/* Return */
return (string) $table;
@@ -93,10 +102,10 @@ class _{class}
...
);
* @endcode
* @param \IPS\Member $member The member
* @return array|NULL
* @param MemberClass $member The member
* @return array|Select
*/
public function findByMember( $member )
public function findByMember( MemberClass $member ): array|Select
{
return array();
}
@@ -12,16 +12,21 @@
namespace IPS\{app}\extensions\core\LiveSearch;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Dispatcher;
use IPS\Extensions\LiveSearchAbstract;
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;
}
/**
* @brief ACP Live Search Extension
*/
class _{class}
class {class} extends LiveSearchAbstract
{
/**
* Constructor
@@ -39,7 +44,7 @@ class _{class}
* @param string $searchTerm Search Term
* @return array Array of results
*/
public function getResults( $searchTerm ): array
public function getResults( string $searchTerm ): array
{
return array();
}
@@ -62,6 +67,6 @@ class _{class}
*/
public function isDefault(): bool
{
return \IPS\Dispatcher::i()->application->directory == 'myapp';
return Dispatcher::i()->application->directory == '{app}';
}
}
@@ -0,0 +1,74 @@
<?php
namespace IPS\{app}\extensions\core\Loader;
use IPS\Extensions\LoaderAbstract;
use IPS\Http\Url;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Loader extension: {class}
*/
class {class} extends LoaderAbstract
{
/**
* Additional CSS files to load
*
* @return array<string|Url>
*/
public function css(): array
{
return [];
}
/**
* Additional JS files to load
*
* @return array<string|Url>
*/
public function js(): array
{
return [];
}
/**
* If a redirect is needed, return the URL
* or NULL to continue
*
* @return Url|null
*/
public function checkForRedirect() : Url|null
{
return null;
}
/**
* Show a custom error message or null to use the default
*
* @param string $message
* @param mixed $code
* @param int $httpStatusCode
* @return string|null
*/
public function customError( string $message, mixed $code, int $httpStatusCode ) : string|null
{
return null;
}
/**
* Run custom code right on Dispatcher::finish()
*
* @return void
*/
public function onFinish() : void
{
}
}
@@ -0,0 +1,151 @@
<?php
/**
* @brief Account Settings Extension
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\LoginHandler;
use IPS\Login;
use IPS\Login\Exception;
use IPS\Login\Handler;
use IPS\Login\Handler\ButtonHandler;
use IPS\Login\Handler\UsernamePasswordHandler;
use IPS\Member as MemberClass;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* AccountSettings Extension
*/
class {class} extends Handler
{
// @todo Uncomment one or both of the following
//use UsernamePasswordHandler; // Uncomment this to implement a username/password handler
//use ButtonHandler; // Uncomment this to implement a button handler
/**
* Get type
*
* @return int
*/
public function type(): int
{
return Login::TYPE_USERNAME_PASSWORD; // Login::TYPE_BUTTON;
}
/**
* Get title
*
* @return string
*/
public static function getTitle(): string
{
return '';
}
/**
* ACP Settings Form
*
* @return array List of settings to save - settings will be stored to core_login_methods.login_settings DB field
* @code
return array( 'savekey' => new \IPS\Helpers\Form\[Type]( ... ), ... );
* @endcode
*/
public function acpForm(): array
{
return array();
}
/**
* Save Handler Settings
*
* @param array $values Values from form
* @return array
*/
public function acpFormSave( array &$values ): array
{
return parent::acpFormSave( $values );
}
/* !UsernamePassword Authentication */
/**
* Authenticate
*
* @param Login $login The login object
* @param string $usernameOrEmail The username or email address provided by the user
* @param object $password The plaintext password provided by the user, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return MemberClass
* @throws Exception
*/
/*public function authenticateUsernamePassword(Login $login, string $usernameOrEmail, object $password): MemberClass
{
// TODO: Implement authenticateUsernamePassword() method.
}*/
/**
* Authenticate
*
* @param MemberClass $member The member
* @param object $password The plaintext password provided by the user, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return bool
*/
/*public function authenticatePasswordForMember(MemberClass $member, object $password): bool
{
// TODO: Implement authenticatePasswordForMember() method.
}*/
/* !Button Authentication */
/**
* Authenticate
*
* @param Login $login The login object
* @throws Exception
*/
/*public function authenticateButton(Login $login)
{
// TODO: Implement authenticateButton() method.
}*/
/**
* Get the button color
*
* @return string
*/
/*public function buttonColor(): string
{
// TODO: Implement buttonColor() method.
}*/
/**
* Get the button icon
*
* @return string
*/
/*public function buttonIcon(): string
{
// TODO: Implement buttonIcon() method.
}*/
/**
* Get button text
*
* @return string
*/
/*public function buttonText(): string
{
// TODO: Implement buttonText() method.
}*/
}
@@ -11,17 +11,20 @@
namespace IPS\{app}\extensions\core\MFAArea;
use IPS\Extensions\MFAAreaAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Multi-Factor Authentication Area
*/
class _{class}
class {class} extends MFAAreaAbstract
{
/**
* Is this area available and should show in the ACP configuration?
@@ -11,18 +11,38 @@
namespace IPS\{app}\extensions\core\MemberACPProfileBlocks;
use IPS\core\MemberACPProfile\Block;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 ACP Member Profile Block
*/
class _{class} extends \IPS\core\MemberACPProfile\Block
class {class} extends Block
{
/**
* Optionally show this profile block on a tab outside of your application.
* Example: to show on the main profile tab, set this to 'core_Main'.
*
* @var string
*/
public static string $displayTab = '';
/**
* Used in conjunction with static::$displayTab.
* If showing on a profile tab outside of your application,
* set this to 'left' or 'main' to place it in the proper column.
*
* @var string
*/
public static string $displayColumn = '';
/**
* Get output
*
@@ -11,17 +11,20 @@
namespace IPS\{app}\extensions\core\MemberACPProfileContentTab;
use IPS\core\MemberACPProfile\Block;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Member ACP Profile
*/
class _{class} extends \IPS\core\MemberACPProfile\Block
class {class} extends Block
{
/**
* Get output
@@ -11,17 +11,20 @@
namespace IPS\{app}\extensions\core\MemberACPProfileTabs;
use IPS\core\MemberACPProfile\MainTab;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 ACP Member Profile Tab
*/
class _{class} extends \IPS\core\MemberACPProfile\MainTab
class {class} extends MainTab
{
/**
* Get left-column blocks
@@ -11,25 +11,29 @@
namespace IPS\{app}\extensions\core\MemberExportPersonalInformation;
use IPS\Extensions\MemberExportPiiAbstract;
use IPS\Member as MemberClass;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 ACP Export Personal Information
*/
class _{class}
class {class} extends MemberExportPiiAbstract
{
/**
* Return data
* @param \IPS\Member $member The member
* @param MemberClass $member The member
*
* @return array
*/
public function getData( \IPS\Member $member ): array
public function getData( MemberClass $member ): array
{
$return = array();
return $return;
@@ -11,36 +11,45 @@
namespace IPS\{app}\extensions\core\MemberFilter;
use IPS\Db\Select;
use IPS\Extensions\MemberFilterAbstract;
use IPS\Member as MemberClass;
use LogicException;
use function defined;
use function in_array;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Member Filter Extension
*/
class _{class}
class {class} extends MemberFilterAbstract
{
/**
* Determine if the filter is available in a given area
*
* @param string $area Area to check
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation, passwordreset)
* @return bool
*/
public function availableIn( $area ): bool
public function availableIn( string $area ): bool
{
return \in_array( $area, array( 'bulkmail', 'group_promotions' ) );
return in_array( $area, array(
{areas}
) );
}
/**
* Get Setting Field
*
* @param mixed $criteria Value returned from the save() method
* @param array $criteria Value returned from the save() method
* @return array Array of form elements
*/
public function getSettingField( $criteria ): array
public function getSettingField( array $criteria ): array
{
return array();
}
@@ -49,10 +58,10 @@ class _{class}
* Save the filter data
*
* @param array $post Form values
* @return mixed False, or an array of data to use later when filtering the members
* @throws \LogicException
* @return array|bool False, or an array of data to use later when filtering the members
* @throws LogicException
*/
public function save( $post )
public function save( array $post ) : array|bool
{
return FALSE;
}
@@ -60,10 +69,10 @@ class _{class}
/**
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @param array $data The array returned from the save() method
* @return array|NULL Where clause - must be a single array( "clause" )
*/
public function getQueryWhereClause( $data )
public function getQueryWhereClause( array $data ): ?array
{
return NULL;
}
@@ -72,25 +81,25 @@ class _{class}
* Callback for member retrieval database query
* Can be used to set joins
*
* @param mixed $data The array returned from the save() method
* @param \IPS\Db\Query $query The query
* @param array $data The array returned from the save() method
* @param Select $query The query
* @return void
*/
public function queryCallback( $data, &$query )
public function queryCallback( array $data, Select $query ) : void
{
return NULL;
}
/**
* Determine if a member matches specified filters
*
* @note This is only necessary if availableIn() includes group_promotions
* @param \IPS\Member $member Member object to check
* @param MemberClass $member Member object to check
* @param array $filters Previously defined filters
* @param object|NULL $object Calling class
* @return bool
*/
public function matches( \IPS\Member $member, $filters, $object=NULL ): bool
public function matches( MemberClass $member, array $filters, ?object $object=NULL ): bool
{
return TRUE;
}
@@ -1,49 +0,0 @@
<?php
/**
* @brief Admin CP Member Form
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\MemberForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Member Form
*/
class _{class}
{
/**
* Process Form
*
* @param \IPS\Helpers\Form $form The form
* @param \IPS\Member $member Existing Member
* @return void
*/
public function process( &$form, $member )
{
$form->add( new \IPS\Helpers\Form\Text( 'example' ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member $member The member
* @return void
*/
public function save( $values, &$member )
{
$member->example = $values['example'];
}
}
@@ -11,17 +11,20 @@
namespace IPS\{app}\extensions\core\MemberHistory;
use IPS\Extensions\MemberHistoryAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Member History: {class}
*/
class _{class}
class {class} extends MemberHistoryAbstract
{
/**
* Return the valid member history log types
@@ -40,7 +43,7 @@ class _{class}
* @param array $row entire log row
* @return string
*/
public function parseLogType( $value, $row ): string
public function parseLogType( string $value, array $row ): string
{
return $value;
}
@@ -52,7 +55,7 @@ class _{class}
* @param array $row entire log row
* @return string
*/
public function parseLogData( $value, $row ): string
public function parseLogData( string $value, array $row ): string
{
return $value;
}
@@ -11,25 +11,31 @@
namespace IPS\{app}\extensions\core\MemberRestrictions;
use IPS\core\MemberACPProfile\Restriction;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Member as MemberClass;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Member Restrictions
*/
class _{class} extends \IPS\core\MemberACPProfile\Restriction
class {class} extends Restriction
{
/**
* Modify Edit Restrictions form
*
* @param \IPS\Helpers\Form $form The form
* @param Form $form The form
* @return void
*/
public function form( \IPS\Helpers\Form $form )
public function form( Form $form ) : void
{
// $form->add( ... );
}
@@ -40,12 +46,12 @@ class _{class} extends \IPS\core\MemberACPProfile\Restriction
* @param array $values Values from form
* @return array
*/
public function save( $values ): array
public function save( array $values ): array
{
$return = array();
// $return['my_restriction'] = array( 'old' => $oldValue, 'new' => $values['my_restriction'] ); // used in changesForHistory()
// \IPS\Db::i()->update( ... ); // Actually save the value
// Db::i()->update( ... ); // Actually save the value
return $return;
}
@@ -80,7 +86,7 @@ class _{class} extends \IPS\core\MemberACPProfile\Restriction
if ( isset( $changes['my_restriction'] ) )
{
$return[] = \IPS\Member::loggedIn()->language()->addToStack( 'changed_my_restriction', FALSE, array( 'sprintf' => array( $changes['my_restriction']['new'], $changes['my_restriction']['new'] ) ) );
$return[] = MemberClass::loggedIn()->language()->addToStack( 'changed_my_restriction', FALSE, array( 'sprintf' => array( $changes['my_restriction']['new'], $changes['my_restriction']['new'] ) ) );
}
return $return;
@@ -1,152 +0,0 @@
<?php
/**
* @brief Member Sync
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\MemberSync;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Sync
*/
class _{class}
{
/**
* Member account has been created
*
* @param $member \IPS\Member New member account
* @return void
*/
public function onCreateAccount( $member )
{
}
/**
* Member has validated
*
* @param \IPS\Member $member Member validated
* @return void
*/
public function onValidate( $member )
{
}
/**
* Member has logged on
*
* @param \IPS\Member $member Member that logged in
* @return void
*/
public function onLogin( $member )
{
}
/**
* Member has logged out
*
* @param \IPS\Member $member Member that logged out
* @param \IPS\Http\Url $returnUrl The URL to send the user back to
* @return void
*/
public function onLogout( $member, $returnUrl )
{
}
/**
* Member account has been updated
*
* @param $member \IPS\Member Member updating profile
* @param $changes array The changes
* @return void
*/
public function onProfileUpdate( $member, $changes )
{
}
/**
* Member is flagged as spammer
*
* @param $member \IPS\Member The member
* @return void
*/
public function onSetAsSpammer( $member )
{
}
/**
* Member is unflagged as spammer
*
* @param $member \IPS\Member The member
* @return void
*/
public function onUnSetAsSpammer( $member )
{
}
/**
* Member is merged with another member
*
* @param \IPS\Member $member Member being kept
* @param \IPS\Member $member2 Member being removed
* @return void
*/
public function onMerge( $member, $member2 )
{
}
/**
* Member is deleted
*
* @param $member \IPS\Member The member
* @return void
*/
public function onDelete( $member )
{
}
/**
* Email address is changed
*
* @param \IPS\Member $member The member
* @param string $new New email address
* @param string $old Old email address
* @return void
*/
public function onEmailChange( $member, $new, $old )
{
}
/**
* Password is changed
*
* @param \IPS\Member $member The member
* @param string $new New password, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return void
*/
public function onPassChange( $member, $new )
{
}
}
@@ -11,17 +11,19 @@
namespace IPS\{app}\extensions\core\MetaData;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Meta Data: {class}
*/
class _{class}
class {class}
{
}
@@ -11,25 +11,40 @@
namespace IPS\{app}\extensions\core\ModCp;
use IPS\Extensions\ModCpAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Moderator Control Panel Extension: {class}
*/
class _{class}
class {class} extends ModCpAbstract
{
/**
* Returns the primary tab key for the navigation bar
*
* @return string|null
*/
public function getTab()
public function getTab() : ?string
{
return '{tabKey}';
}
/**
* What do I manage?
* Acceptable responses are: content, members, or other
*
* @return string
*/
public function manageType() : string
{
return '{manageType}';
}
/**
@@ -37,7 +52,7 @@ class _{class}
*
* @return void
*/
public function manage()
public function manage() : void
{
}
@@ -11,25 +11,29 @@
namespace IPS\{app}\extensions\core\ModCpMemberManagement;
use IPS\Extensions\ModCpMemberManagementAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Moderator Control Panel Member Management Extension: {class}
*/
class _{class}
class {class} extends ModCpMemberManagementAbstract
{
/**
* Returns the tab key for the navigation bar
*
* @return string|null
*/
public function getTab()
public function getTab() : ?string
{
return '{class}';
}
/**
@@ -37,7 +41,8 @@ class _{class}
*
* @return string
*/
public function manage()
public function manage() : string
{
return '';
}
}
@@ -12,20 +12,25 @@
namespace IPS\{app}\extensions\core\ModeratorPermissions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\ModeratorPermissionsAbstract;
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;
}
/**
* Moderator Permissions
*/
class _{class}
class {class} extends ModeratorPermissionsAbstract
{
/**
* Get Permissions
*
* @param array $toggles
* @code
return array(
'key' => 'YesNo', // Can just return a string with type
@@ -40,23 +45,14 @@ class _{class}
* @endcode
* @return array
*/
public function getPermissions(): array
public function getPermissions( array $toggles ): array
{
return array();
return array(
/*'can_edit_course_content' => "YesNo",
'can_delete_course_content' => "YesNo",*/
);
}
/**
* Pre-save
*
* @note This can be used to adjust the values submitted on the form prior to saving
* @param array $values The submitted form values
* @return void
*/
public function preSave( &$values )
{
}
/**
* After change
*
@@ -64,19 +60,19 @@ class _{class}
* @param array $changed Values that were changed
* @return void
*/
public function onChange( $moderator, $changed )
public function onChange( array $moderator, array $changed ) : void
{
}
/**
* After delete
*
* @param array $moderator The moderator
* @return void
*/
public function onDelete( $moderator )
public function onDelete( array $moderator ) : void
{
}
}
@@ -11,25 +11,31 @@
namespace IPS\{app}\extensions\core\Notifications;
use IPS\Extensions\NotificationsAbstract;
use IPS\Http\Url;
use IPS\Member as MemberClass;
use IPS\Notification\Inline;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Notification Options
*/
class _{class}
class {class} extends NotificationsAbstract
{
/**
* Get fields for configuration
*
* @param \IPS\Member|null $member The member (to take out any notification types a given member will never see) or NULL if this is for the ACP
* @param MemberClass|null $member The member (to take out any notification types a given member will never see) or NULL if this is for the ACP
* @return array
*/
public static function configurationOptions( \IPS\Member $member = NULL ): array
public static function configurationOptions( ?MemberClass $member = NULL ): array
{
// Return an array defining each notification type, including the form elements necessary to allow its configuration
@@ -37,7 +43,7 @@ class _{class}
'setting_key' => array(
'type' => 'custom',
'adminCanSetDefault'=> TRUE,
'field' => \IPS\Helpers\Form\CheckboxSet( 'setting_key', $defaultValue, FALSE, /*...*/ ),
'field' => new \IPS\Helpers\Form\CheckboxSet( 'setting_key', null, FALSE, /*...*/ ),
'admin_lang' => array(
'header' => 'header_lang_key',
'title' => 'header_lang_title',
@@ -46,7 +52,7 @@ class _{class}
'other_setting_key' => array(
'type' => 'custom',
'adminCanSetDefault'=> FALSE,
'field' => $formField,
'field' => new \IPS\Helpers\Form\CheckboxSet( 'other_setting_key', null, false ),
),
'separator1' => array(
'type' => 'separator',
@@ -58,12 +64,12 @@ class _{class}
/**
* Save "extra" value
*
* @param \IPS\Member|NULL $member The member or NULL if this is the admin setting defaults
* @param string $key The key
* @param bool $value The value
* @param MemberClass|NULL $member The member or NULL if this is the admin setting defaults
* @param string $key The key
* @param bool $value The value
* @return void
*/
public static function saveExtra( ?\IPS\Member $member, $key, $value )
public static function saveExtra( ?MemberClass $member, string $key, bool $value ) : void
{
// You can perform extra processing here to save values in a specific manner if needed
}
@@ -71,11 +77,11 @@ class _{class}
/**
* Disable all "extra" values for a particular type
*
* @param \IPS\Member|NULL $member The member or NULL if this is the admin setting defaults
* @param string $method The method type
* @param MemberClass|NULL $member The member or NULL if this is the admin setting defaults
* @param string $method The method type
* @return void
*/
public static function disableExtra( ?\IPS\Member $member, $method )
public static function disableExtra( ?MemberClass $member, string $method ) : void
{
// You can disable extra values for a given type, such as if a setting means the notification preference is irrelevant
}
@@ -85,7 +91,7 @@ class _{class}
*
* @return void
*/
public static function resetExtra()
public static function resetExtra() : void
{
// Any extra processing you may need to perform when resetting all members to default notification options.
// Typically you won't have to do anything here unless you have custom settings
@@ -97,29 +103,29 @@ class _{class}
/**
* Parse notification: key
*
* @param \IPS\Notification\Inline $notification The notification
* @param bool $htmlEscape TRUE to escape HTML in title
* @param Inline $notification The notification
* @param bool $htmlEscape TRUE to escape HTML in title
* @return array
* @code
return array(
'title' => "Mark has replied to A Topic", // The notification title
'url' => \IPS\Http\Url::internal( ... ), // The URL the notification should link to
'url' => Url::internal( ... ), // The URL the notification should link to
'content' => "Lorem ipsum dolar sit", // [Optional] Any appropriate content. Do not format this like an email where the text
// explains what the notification is about - just include any appropriate content.
// For example, if the notification is about a post, set this as the body of the post.
'author' => \IPS\Member::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
'author' => MemberClass::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
);
* @endcode
*/
public function parse_key( \IPS\Notification\Inline $notification, $htmlEscape=TRUE ): array
public function parse_key( Inline $notification, bool $htmlEscape=TRUE ): array
{
return array(
'title' => "Mark has replied to A Topic", // The notification title
'url' => \IPS\Http\Url::internal( '' ), // The URL the notification should link to
'url' => Url::internal( '' ), // The URL the notification should link to
'content' => "Lorem ipsum dolar sit", // [Optional] Any appropriate content. Do not format this like an email where the text
// explains what the notification is about - just include any appropriate content.
// For example, if the notification is about a post, set this as the body of the post.
'author' => \IPS\Member::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
'author' => MemberClass::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
);
}
}
@@ -11,17 +11,20 @@
namespace IPS\{app}\extensions\core\OutputPlugins;
use IPS\Extensions\OutputPluginsAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Template Plugin
*/
class _{class}
class {class} extends OutputPluginsAbstract
{
/**
* @brief Can be used when compiling CSS
@@ -35,7 +38,8 @@ class _{class}
* @param array $options Array of options
* @return array|string string with code to eval or array( 'pre' => Code to eval before 'return', 'return' => Code to eval to return desired value )
*/
public static function runPlugin( $data, $options )
public static function runPlugin( string $data, array $options ): string|array
{
return '';
}
}
@@ -11,22 +11,25 @@
namespace IPS\{app}\extensions\core\OverviewStatistics;
use IPS\Extensions\OverviewStatisticsAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Overview statistics extension: {class}
*/
class _{class}
class {class} extends OverviewStatisticsAbstract
{
/**
* @brief Which statistics page (activity or user)
*/
public $page = 'user';
public string $page = '{statisticsPage}';
/**
* Return the sub-block keys
@@ -45,20 +48,20 @@ class _{class}
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
* @return array
*/
public function getBlockDetails( $subBlock = NULL ): array
public function getBlockDetails( ?string $subBlock = NULL ): array
{
/* Description can be null and will not be shown if so */
return array( 'app' => '...', 'title' => '...', 'description' => null, 'refresh' => 60 );
return array( 'app' => '{app}', 'title' => '...', 'description' => null, 'refresh' => 60 );
}
/**
* Return the block HTML to show
*
* @param array|NULL $dateRange NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
* @param array|string|null $dateRange String for a fixed time period in days, NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
* @return string
*/
public function getBlock( $dateRange = NULL, $subBlock = NULL ): string
public function getBlock( array|string|null $dateRange = NULL, ?string $subBlock = NULL ): string
{
return '';
}
@@ -11,17 +11,20 @@
namespace IPS\{app}\extensions\core\Permissions;
use IPS\Extensions\PermissionsAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Permissions
*/
class _{class}
class {class} extends PermissionsAbstract
{
/**
* Get node classes
@@ -30,7 +33,7 @@ class _{class}
*/
public function getNodeClasses(): array
{
return array();
return array( '{node}' );
}
}
@@ -11,34 +11,21 @@
namespace IPS\{app}\extensions\core\Profile;
use IPS\Extensions\ProfileAbstract;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 Profile extension: {class}
*/
class _{class}
class {class} extends ProfileAbstract
{
/**
* Member
*/
protected $member;
/**
* Constructor
*
* @param \IPS\Member $member Member whose profile we are viewing
* @return void
*/
public function __construct( \IPS\Member $member )
{
$this->member = $member;
}
/**
* Is there content to display?
*
@@ -11,17 +11,24 @@
namespace IPS\{app}\extensions\core\ProfileSteps;
use IPS\Extensions\ProfileStepsAbstract;
use IPS\Helpers\Form;
use IPS\Http\Url;
use IPS\Member as MemberClass;
use IPS\Member\ProfileStep;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Profile Completion Extension
*/
class _{class}
class {class} extends ProfileStepsAbstract
{
/**
* Available Actions to complete steps
@@ -47,9 +54,9 @@ class _{class}
* Can the actions have multiple choices?
*
* @param string $action Action key (basic_profile, etc)
* @return boolean
* @return bool|null
*/
public static function actionMultipleChoice( $action ): bool
public static function actionMultipleChoice( string $action ): ?bool
{
return FALSE;
}
@@ -57,11 +64,11 @@ class _{class}
/**
* Has a specific step been completed?
*
* @param \IPS\Member\ProfileStep $step The step to check
* @param \IPS\Member|NULL $member The member to check, or NULL for currently logged in
* @param ProfileStep $step The step to check
* @param MemberClass|NULL $member The member to check, or NULL for currently logged in
* @return bool
*/
public function completed( \IPS\Member\ProfileStep $step, \IPS\Member $member = NULL ): bool
public function completed( ProfileStep $step, ?MemberClass $member = NULL ): bool
{
return FALSE;
}
@@ -81,22 +88,22 @@ class _{class}
* Action URL
*
* @param string $action The action
* @param \IPS\Member|NULL $member The member, or NULL for currently logged in
* @return \IPS\Http\Url
* @param MemberClass|NULL $member The member, or NULL for currently logged in
* @return Url|null
*/
public function url( $action, \IPS\Member $member = NULL ): \IPS\Http\Url
public function url( string $action, ?MemberClass $member = NULL ): ?Url
{
return \IPS\Http\Url::internal( '' );
return null;
}
/**
* Post ACP Save
*
* @param \IPS\Member\ProfileStep $step The step
* @param array $values Form Values
* @param ProfileStep $step The step
* @param array $values Form Values
* @return void
*/
public function postAcpSave( \IPS\Member\ProfileStep $step, array $values )
public function postAcpSave( ProfileStep $step, array $values ) : void
{
}
@@ -104,12 +111,12 @@ class _{class}
/**
* Format Form Values
*
* @param array $values The values from the form
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form $form The form
* @param array $values The values from the form
* @param MemberClass $member The member
* @param Form $form The form
* @return void
*/
public static function formatFormValues( $values, &$member, &$form )
public static function formatFormValues( array $values, MemberClass $member, Form $form ) : void
{
}
@@ -117,10 +124,10 @@ class _{class}
/**
* Wizard Steps
*
* @param \IPS\Member $member Member or NULL for currently logged in member
* @return array
* @param MemberClass|null $member Member or NULL for currently logged in member
* @return array|string
*/
public static function wizard( \IPS\Member $member = NULL ): array
public static function wizard( ?MemberClass $member = NULL ): array|string
{
return array( );
}
@@ -128,10 +135,10 @@ class _{class}
/**
* Post Delete
*
* @param \IPS\Member\ProfileStep The step
* @param ProfileStep $step The step
* @return void
*/
public function onDelete( \IPS\Member\ProfileStep $step )
public function onDelete( ProfileStep $step ) : void
{
}
@@ -11,25 +11,30 @@
namespace IPS\{app}\extensions\core\Queue;
use IPS\Extensions\QueueAbstract;
use IPS\Task\Queue\OutOfRangeException as QueueOutOfRangeException;
use OutOfRangeException;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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;
}
/**
* Background Task
*/
class _{class}
class {class} extends QueueAbstract
{
/**
* Parse data before queuing
*
* @param array $data
* @return array
* @return array|null
*/
public function preQueueData( $data ): ?array
public function preQueueData( array $data ): ?array
{
return $data;
}
@@ -37,25 +42,25 @@ class _{class}
/**
* Run Background Task
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param array $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
* @throws QueueOutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
public function run( array &$data, int $offset ): int
{
return $offset;
}
/**
* Get Progress
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param array $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset ): array
public function getProgress( array $data, int $offset ): array
{
return array( 'text' => 'Doing something...', 'complete' => 50 );
}
@@ -67,7 +72,7 @@ class _{class}
* @param bool $processed Was anything processed or not? If preQueueData returns NULL, this will be FALSE.
* @return void
*/
public function postComplete( $data, $processed = TRUE )
public function postComplete( array $data, bool $processed = TRUE ) : void
{
}
@@ -11,23 +11,23 @@
namespace IPS\{app}\extensions\core\RssImport;
use IPS\core\Rss\Import;
use IPS\Extensions\RssImportAbstract;
use IPS\Helpers\Form;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
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 RSS Import extension: {class}
*/
class _{class}
class {class} extends RssImportAbstract
{
/**
* @brief RSSImport Classes
*/
public $classes = array();
/**
* Constructor
*
@@ -35,16 +35,17 @@ class _{class}
*/
public function __construct()
{
$this->classes[] = 'IPS\{app}\{example}';
$this->classes[] = '{item}';
}
/**
* Display Form
*
* @param \IPS\Helpers\Form $form The form
* @param Form $form The form
* @param Import|null $rss Existing RSS object if editing|null if not
* @return void
*/
public function form( \IPS\Helpers\Form &$form )
public function form( Form $form, ?Import $rss=null ) : void
{
$form->add( new \IPS\Helpers\Form\Text( 'example' ) );
}
@@ -53,9 +54,10 @@ class _{class}
* Save
*
* @param array $values Values from form
* @return void
* @param Import $rss Existing RSS object
* @return array
*/
public function saveForm( $values)
public function saveForm( array &$values, Import $rss ) : array
{
return $values;
}
@@ -0,0 +1,116 @@
<?php
/**
* @brief SSO Extension
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\SSO;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Extensions\SSOAbstract;
use IPS\Session\Front;
use IPS\Http\Url;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* SSO Extension
*/
class {class} extends SSOAbstract
{
/**
* Determine if the extension is currently enabled
*
* @return bool
*/
public function isEnabled(): bool
{
return true;
}
/**
* Returns an array of setting keys that will be overridden by this extension
* Example: post_before_registering might always return a value of 0
* Would return an array like [ 'post_before_registering' => 0 ]
*
* @return array
*/
public function overrideSettings(): array
{
return [];
}
/**
* Return URL guest should be redirected to for login
*
* @return Url|null
*/
public function loginUrl(): Url|null
{
return NULL;
}
/**
* Return URL guest should be redirect to for login
*
* @param Url $redirectUrl
* @return Url|null
*/
public function logoutUrl( Url $redirectUrl ): Url|null
{
return NULL;
}
/**
* Return URL user should visit to change display name
*
* @return Url|null
*/
public function displayNameChange(): Url|null
{
return NULL;
}
/**
* Custom logic executed on session init
*
* @param Front $session
* @return void
*/
public function onSessionInit( Front $session ): void
{
}
/**
* Custom logic executed on session read
*
* @param Front $session
* @param string $result Initial result from the Session::read method
* @return string
*/
public function onSessionRead( Front $session, string $result ): string
{
return '';
}
/**
* Does SSO support login as?
*
* @return bool
*/
public function supportsLoginAs(): bool
{
return FALSE;
}
}
@@ -0,0 +1,40 @@
<?php
/**
* @brief SearchContent extension: {class}
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
{subpackage}
* @since {date}
*/
namespace IPS\{app}\extensions\core\SearchContent;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Content\Search\SearchContentAbstract;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief SearchContent extension: {class}
*/
class {class} extends SearchContentAbstract
{
/**
* Return all searchable classes in your application,
* including comments and/or reviews
*
* @return array
*/
public static function supportedClasses() : array
{
return array();
}
}
@@ -12,25 +12,30 @@
namespace IPS\{app}\extensions\core\SearchIndex;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content as ContentClass;
use IPS\Content\Search\SearchIndexAbstract;
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;
}
/**
* Search Index
*/
class _{class}
class {class} extends SearchIndexAbstract
{
/**
* Alter index_content before it is stored
*
* @param \IPS\Content $object The class object (eg: \IPS\forums\Topic\Post)
* @param string $content The HTML stripped content
* @param ContentClass $object The class object (eg: \IPS\forums\Topic\Post)
* @param string $content The HTML stripped content
* @return string
*/
public function content( $object, $content ): string
public function content( ContentClass $object, string $content ): string
{
return $content;
}
@@ -12,21 +12,27 @@
namespace IPS\{app}\extensions\core\Sitemap;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\SitemapAbstract;
use IPS\Settings as SettingsClass;
use IPS\Sitemap;
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;
}
/**
* Support {class} in sitemaps
*/
class _{class}
class {class} extends SitemapAbstract
{
/**
* @brief Recommended Settings
*/
public $recommendedSettings = array();
public array $recommendedSettings = array();
/**
* Add settings for ACP configuration to the form
@@ -44,17 +50,17 @@ class _{class}
* @param array $values Values
* @return void
*/
public function saveSettings( $values )
public function saveSettings( array $values ) : void
{
if ( $values['sitemap_configuration_info'] )
{
// Store default values for any settings you define
//\IPS\Settings::i()->changeValues( array( ) );
//SettingsClass::i()->changeValues( array( ) );
}
else
{
// Store the actual submitted value for any settings you define, from the $values array
//\IPS\Settings::i()->changeValues( array( ) );
//SettingsClass::i()->changeValues( array( ) );
}
}
@@ -71,12 +77,13 @@ class _{class}
/**
* Generate the sitemap
*
* @param string $filename The sitemap file to build (should be one returned from getFilenames())
* @param \IPS\Sitemap $sitemap Sitemap object reference
* @return void
* @param string $filename The sitemap file to build (should be one returned from getFilenames())
* @param Sitemap $sitemap Sitemap object reference
* @return int|null
*/
public function generateSitemap( $filename, $sitemap )
public function generateSitemap( string $filename, Sitemap $sitemap ) : ?int
{
return null;
}
}
@@ -10,37 +10,34 @@
namespace IPS\{app}\extensions\core\Statistics;
use IPS\core\Statistics\Chart as ParentClass;
use IPS\Helpers\Chart;
use IPS\core\Statistics\Chart;
use IPS\Helpers\Chart as ChartClass;
use IPS\Http\Url;
use function defined;
use function header;
/* To prevent PHP errors (extending class does not exist) revealing path */
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;
}
/**
* Statistics Chart Extension
*/
class _{class} extends ParentClass
class {class} extends Chart
{
/**
* @brief Controller
*/
public $controller = NULL;
public ?string $controller = NULL;
/**
* Render Chart
*
* @param \IPS\Http\Url $url URL the chart is being shown on.
* @return \IPS\Helpers\Chart
* @param Url $url URL the chart is being shown on.
* @return ChartClass
*/
public function getChart( Url $url ): Chart
public function getChart( Url $url ): ChartClass
{
}
@@ -12,26 +12,31 @@
namespace IPS\{app}\extensions\core\StreamItems;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\StreamItemsAbstract;
use IPS\Member as MemberClass;
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;
}
/**
* @brief Activity stream items extension: {class}
*/
class _{class}
class {class} extends StreamItemsAbstract
{
/**
* Is there content to display?
*
* @param \IPS\Member|NULL $author The author to limit extra items to
* @param Timestamp|NULL $lastTime If provided, only items since this date are included. If NULL, it works out which to include based on what results are being shown
* @param Timestamp|NULL $firstTime If provided, only items before this date are included. If NULL, it works out which to include based on what results are being shown
* @param MemberClass|NULL $author The author to limit extra items to
* @param int|NULL $lastTime If provided, only items since this date are included. If NULL, it works out which to include based on what results are being shown
* @param int|NULL $firstTime If provided, only items before this date are included. If NULL, it works out which to include based on what results are being shown
* @return array Array of \IPS\Content\Search\Result\Custom objects
*/
public function extraItems( $author=NULL, $lastTime=NULL, $firstTime=NULL ): array
public function extraItems( ?MemberClass $author=NULL, ?int $lastTime=NULL, ?int $firstTime=NULL ): array
{
// Note!
// Your application must define a setting and a language string in the format of "all_activity_{application}_{extensionname}" all in lower case. Without this, this plugin will not be executed.
@@ -0,0 +1,97 @@
<?php
namespace IPS\{app}\extensions\core\UIComment;
use IPS\Content\Comment as BaseComment;
use IPS\Content\Item as BaseItem;
use IPS\Helpers\Form\FormAbstract;
use IPS\Helpers\Menu\MenuItem;
use IPS\Output\UI\Comment as UIComment;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content UI extension: {class}
*/
class {class} extends UIComment
{
/**
* @brief Class to extend
*/
public static ?string $class = '{comment}';
/**
* Can be used to add additional css classes to the comment
*
* @param BaseComment $comment
* @return string
*/
public function css( BaseComment $comment ): string
{
return '';
}
/**
* Can be used to add additional data attributes to the comment
*
* @param BaseComment $comment
* @return string
*/
public function dataAttributes( BaseComment $comment ): string
{
return '';
}
/**
* Can be used to attach additional content to the author panel
*
* @param BaseComment $comment
* @return string
*/
public function authorPanel( BaseComment $comment ): string
{
return '';
}
/**
* returns additional menu items for the comment menu
*
* @param BaseComment $comment
* @return array<string,MenuItem>
*/
public function menuItems( BaseComment $comment ): array
{
return [];
}
/**
* Add elements to the comment form
*
* @param BaseComment|null $comment
* @param BaseItem $item
* @return array<string,FormAbstract>
*/
public function formElements( ?BaseComment $comment, BaseItem $item ): array
{
return [];
}
/**
* Triggered after the comment form is saved
*
* @param BaseComment $comment
* @param array $values
* @return void
*/
public function formPostSave( BaseComment $comment, array $values ): void
{
}
}
@@ -0,0 +1,166 @@
<?php
namespace IPS\{app}\extensions\core\UIItem;
use IPS\Content\Item as BaseItem;
use IPS\Helpers\Badge\Icon;
use IPS\Helpers\Form\FormAbstract;
use IPS\Helpers\Table\Content;
use IPS\Node\Model;
use IPS\Output\UI\Item as UIItem;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content UI extension: {class}
*/
class {class} extends UIItem
{
/**
* @brief Class to extend
*/
public static ?string $class = '{item}';
/**
* Can be used to add additional css classes to the item
*
* @param BaseItem $item
* @return string
*/
public function css( BaseItem $item ): string
{
return '';
}
/**
* Can be used to add additional data attributes to the item
*
* @param BaseItem $item
* @return string
*/
public function dataAttributes( BaseItem $item ): string
{
return '';
}
/**
* returns additional menu items for the moderation menu
*
* @param BaseItem $item
* @return array
*/
public function menuItems( BaseItem $item ): array
{
return [];
}
/**
* Returns additional badge icons to display in the header
*
* @param BaseItem $item
* @return array<Icon>
*/
public function badges( BaseItem $item ) : array
{
return [];
}
/**
* Add elements to the item form.
* This method returns all elements that will be added.
* By default, all elements will be added in order at the end of the form.
* To specify placement within the form, @see FormAbstract::setPosition().
*
* @param BaseItem|null $item
* @param Model|null $container
* @return array<string,FormAbstract>
*/
public function formElements( ?BaseItem $item, ?Model $container ): array
{
return [];
}
/**
* Called after the Item form is saved
*
* @param BaseItem $item
* @param array $values
* @return void
*/
public function formPostSave( BaseItem $item, array $values ): void
{
}
/**
* Display content in the contextual sidebar
*
* @param BaseItem $item
* @return string
*/
public function sidebar( BaseItem $item ) : string
{
return "";
}
/**
* Add custom sort options to the content table for this class
* @note $item will ALWAYS be null.
*
* @param BaseItem|null $item
* @param Content $table
* @return array
*/
public function contentTableSortOptions( ?BaseItem $item, Content $table ) : array
{
return [];
}
/**
* Return the sort direction for the selected sort option,
* or NULL to use the default parent method.
*
* @note $item will ALWAYS be null.
*
* @param BaseItem|null $item
* @param Content $table
* @param string $sortBy
* @return string|null
*/
public function contentTableSortDirection( ?BaseItem $item, Content $table, string $sortBy ) : string|null
{
return null;
}
/**
* Add custom filters to the content table for this class
* @note $item will ALWAYS be null.
*
* @param BaseItem|null $item
* @param Content $table
* @return array
*/
public function contentTableFilters( ?BaseItem $item, Content $table ) : array
{
return [];
}
/**
* Add custom conditions to the where clause for a content table.
* @note $item will ALWAYS be null.
*
* @param BaseItem|null $item
* @param Content $table
* @return array
*/
public function contentTableWhere( ?BaseItem $item, Content $table ) : array
{
return [];
}
}
@@ -0,0 +1,109 @@
<?php
namespace IPS\{app}\extensions\core\UINode;
use IPS\Helpers\Form\FormAbstract;
use IPS\Node\Model;
use IPS\Output\UI\Node as UINode;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content UI extension: {class}
*/
class {class} extends UINode
{
/**
* @brief Class to extend
*/
public static ?string $class = '{node}';
/**
* Can be used to add additional css classes to the node
*
* @param Model $node
* @return array
*/
public function css( Model $node ): array
{
return [];
}
/**
* Can be used to add additional data attributes to the node
*
* @param Model $node
* @return string
*/
public function dataAttributes( Model $node ): string
{
return '';
}
/**
* Can be used to add buttons to the ACP tree row
* and to the view page in the ACP
*
* @param Model $node
* @return array
*/
public function rowButtons( Model $node ): array
{
return [];
}
/**
* Returns additional HTML to be displayed in the ACP tree row
*
* @param Model $node
* @return string
*/
public function rowHtml( Model $node ) : string
{
return '';
}
/**
* Return a badge to be displayed in the ACP tree row
*
* @param Model $node
* @return null|array Null for no badge, or an array of badge data (0 => CSS class type, 1 => language string, 2 => optional raw HTML to show instead of language string)
*/
public function rowBadge( Model $node ) : array|null
{
return null;
}
/**
* Add elements to the Node form
* This method returns all elements that will be added.
* By default, all elements will be added in order at the end of the form.
* To specify placement within the form, @see FormAbstract::setPosition().
*
* @param Model $node
* @return array<string,FormAbstract>
*/
public function formElements( Model $node ): array
{
return [];
}
/**
* Called after the Node form is saved
*
* @param Model $node
* @param array $values
* @return void
*/
public function formPostSave( Model $node, array $values ): void
{
}
}
@@ -0,0 +1,97 @@
<?php
namespace IPS\{app}\extensions\core\UIReview;
use IPS\Content\Comment as BaseComment;
use IPS\Content\Item as BaseItem;
use IPS\Helpers\Form\FormAbstract;
use IPS\Helpers\Menu\MenuItem;
use IPS\Output\UI\Review as UIReview;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content UI extension: {class}
*/
class {class} extends UIReview
{
/**
* @brief Class to extend
*/
public static ?string $class = '{review}';
/**
* Can be used to add additional css classes to the comment
*
* @param BaseComment $comment
* @return string
*/
public function css( BaseComment $comment ): string
{
return '';
}
/**
* Can be used to add additional data attributes to the comment
*
* @param BaseComment $comment
* @return string
*/
public function dataAttributes( BaseComment $comment ): string
{
return '';
}
/**
* Can be used to attach additional content to the author panel
*
* @param BaseComment $comment
* @return string
*/
public function authorPanel( BaseComment $comment ): string
{
return '';
}
/**
* returns additional menu items for the comment menu
*
* @param BaseComment $comment
* @return array<string,MenuItem>
*/
public function menuItems( BaseComment $comment ): array
{
return [];
}
/**
* Add elements to the comment form
*
* @param BaseComment|null $comment
* @param BaseItem $item
* @return array<string,FormAbstract>
*/
public function formElements( ?BaseComment $comment, BaseItem $item ): array
{
return [];
}
/**
* Triggered after the comment form is saved
*
* @param BaseComment $comment
* @param array $values
* @return void
*/
public function formPostSave( BaseComment $comment, array $values ): void
{
}
}
@@ -12,16 +12,20 @@
namespace IPS\{app}\extensions\core\Uninstall;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\UninstallAbstract;
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;
}
/**
* Uninstall callback
*/
class _{class}
class {class} extends UninstallAbstract
{
/**
* Code to execute before the application has been uninstalled
@@ -29,7 +33,7 @@ class _{class}
* @param string $application Application directory
* @return void
*/
public function preUninstall( $application )
public function preUninstall( string $application ) : void
{
}
@@ -39,7 +43,7 @@ class _{class}
* @param string $application Application directory
* @return void
*/
public function postUninstall( $application )
public function postUninstall( string $application ) : void
{
}
@@ -47,10 +51,9 @@ class _{class}
* Code to execute when other applications or plugins are uninstalled
*
* @param string $application Application directory
* @param int $plugin Plugin ID
* @return void
*/
public function onOtherUninstall( $application=NULL, $plugin=NULL )
public function onOtherUninstall( string $application ) : void
{
}
}
@@ -0,0 +1,77 @@
<?php
namespace IPS\{app}\extensions\core\UserMenu;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Helpers\Menu\MenuItem;
use IPS\Member as MemberClass;
use IPS\Output\UI\MenuExtension;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief UserMenu extension: {class}
*/
class {class} extends MenuExtension
{
/**
* Used to add additional links to the user account menu
*
* @param string $position ( can be content, settings, logout )
* @return array<MenuItem>
*/
public function accountMenu( string $position = 'content' ): array
{
return [];
}
/**
* Used to add items to the mobile navigation Menu
*
* @param string $position (can be content, settings, logout)
* @return array<MenuItem>
*/
public function mobileMenu( string $position = 'content' ) : array
{
return [];
}
/**
* Used to add additional content to userbar
*
* @return string
*/
public function userNav(): string
{
return '';
}
/**
* Used to add content to the mobile navigation header
*
* @param string $position Where the code will be inserted (header/footer)
* @param string $iconLocation Where the main icons are currently located (header/footer)
* @return string
*/
public function mobileNav( string $position, string $iconLocation = 'footer' ) : string
{
return '';
}
/**
* Used to add items to the user profile menu
*
* @param MemberClass $member Member whose profile is being viewed
* @return array<MenuItem>
*/
public function editProfileMenu( MemberClass $member ) : array
{
return [];
}
}