ENH Add generic types (#2914)

This commit is contained in:
Guy Sartorelli 2024-01-19 10:00:46 +13:00 committed by GitHub
parent a5d2b3bb32
commit 3847b3ea19
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 36 additions and 53 deletions

View File

@ -1038,10 +1038,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
->Link; ->Link;
} }
/**
* @param bool $unlinked
* @return ArrayList
*/
public function Breadcrumbs($unlinked = false) public function Breadcrumbs($unlinked = false)
{ {
$items = new ArrayList(); $items = new ArrayList();
@ -1293,7 +1289,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
if (!$id) { if (!$id) {
$id = $this->currentPageID(); $id = $this->currentPageID();
} }
/** @var SiteTree $record */
$record = $this->getRecord($id); $record = $this->getRecord($id);
// Check parent form can be generated // Check parent form can be generated
@ -1639,7 +1634,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
} }
$gridField = GridField::create('Page', 'Pages', $list, $gridFieldConfig); $gridField = GridField::create('Page', 'Pages', $list, $gridFieldConfig);
$gridField->setAttribute('cms-loading-ignore-url-params', true); $gridField->setAttribute('cms-loading-ignore-url-params', true);
/** @var GridFieldDataColumns $columns */
$columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class); $columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
// Don't allow navigating into children nodes on filtered lists // Don't allow navigating into children nodes on filtered lists
@ -1648,7 +1642,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
'i18n_singular_name' => _t('SilverStripe\\CMS\\Model\\SiteTree.PAGETYPE', 'Page Type'), 'i18n_singular_name' => _t('SilverStripe\\CMS\\Model\\SiteTree.PAGETYPE', 'Page Type'),
'LastEdited' => _t('SilverStripe\\CMS\\Model\\SiteTree.LASTUPDATED', 'Last Updated'), 'LastEdited' => _t('SilverStripe\\CMS\\Model\\SiteTree.LASTUPDATED', 'Last Updated'),
]; ];
/** @var GridFieldSortableHeader $sortableHeader */
$sortableHeader = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class); $sortableHeader = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
$sortableHeader->setFieldSorting(['getTreeTitle' => 'Title']); $sortableHeader->setFieldSorting(['getTreeTitle' => 'Title']);
$gridField->getState()->ParentID = $parentID; $gridField->getState()->ParentID = $parentID;
@ -1891,7 +1884,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
throw new HTTPResponse_Exception("SiteTree #$id not found", 400); throw new HTTPResponse_Exception("SiteTree #$id not found", 400);
} }
/** @var SiteTree $record */
$table = DataObject::singleton(SiteTree::class)->baseTable(); $table = DataObject::singleton(SiteTree::class)->baseTable();
$liveTable = DataObject::singleton(SiteTree::class)->stageTable($table, Versioned::LIVE); $liveTable = DataObject::singleton(SiteTree::class)->stageTable($table, Versioned::LIVE);
$record = Versioned::get_one_by_stage(SiteTree::class, Versioned::LIVE, [ $record = Versioned::get_one_by_stage(SiteTree::class, Versioned::LIVE, [
@ -1964,7 +1956,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
public function archive(array $data, Form $form): HTTPResponse public function archive(array $data, Form $form): HTTPResponse
{ {
$id = $data['ID']; $id = $data['ID'];
/** @var SiteTree $record */
$record = SiteTree::get()->byID($id); $record = SiteTree::get()->byID($id);
if (!$record || !$record->exists()) { if (!$record || !$record->exists()) {
throw new HTTPResponse_Exception("Bad record ID #$id", 404); throw new HTTPResponse_Exception("Bad record ID #$id", 404);
@ -2141,7 +2132,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
} }
$id = (int)$data['ID']; $id = (int)$data['ID'];
/** @var SiteTree $restoredPage */
$restoredPage = Versioned::get_latest_version(SiteTree::class, $id); $restoredPage = Versioned::get_latest_version(SiteTree::class, $id);
if (!$restoredPage) { if (!$restoredPage) {
return new HTTPResponse("SiteTree #$id not found", 400); return new HTTPResponse("SiteTree #$id not found", 400);
@ -2169,7 +2159,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
} }
if (($id = $this->urlParams['ID']) && is_numeric($id)) { if (($id = $this->urlParams['ID']) && is_numeric($id)) {
/** @var SiteTree $page */
$page = SiteTree::get()->byID($id); $page = SiteTree::get()->byID($id);
if ($page && !$page->canCreate(null, ['Parent' => $page->Parent()])) { if ($page && !$page->canCreate(null, ['Parent' => $page->Parent()])) {
return Security::permissionFailure($this); return Security::permissionFailure($this);
@ -2178,7 +2167,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
throw new HTTPResponse_Exception("Bad record ID #$id", 404); throw new HTTPResponse_Exception("Bad record ID #$id", 404);
} }
/** @var SiteTree $newPage */
$newPage = $page->duplicate(); $newPage = $page->duplicate();
// ParentID can be hard-set in the URL. This is useful for pages with multiple parents // ParentID can be hard-set in the URL. This is useful for pages with multiple parents
@ -2213,7 +2201,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
} }
Environment::increaseTimeLimitTo(); Environment::increaseTimeLimitTo();
if (($id = $this->urlParams['ID']) && is_numeric($id)) { if (($id = $this->urlParams['ID']) && is_numeric($id)) {
/** @var SiteTree $page */
$page = SiteTree::get()->byID($id); $page = SiteTree::get()->byID($id);
if ($page && !$page->canCreate(null, ['Parent' => $page->Parent()])) { if ($page && !$page->canCreate(null, ['Parent' => $page->Parent()])) {
return Security::permissionFailure($this); return Security::permissionFailure($this);
@ -2222,7 +2209,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
throw new HTTPResponse_Exception("Bad record ID #$id", 404); throw new HTTPResponse_Exception("Bad record ID #$id", 404);
} }
/** @var SiteTree $newPage */
$newPage = $page->duplicateWithChildren(); $newPage = $page->duplicateWithChildren();
$this->getResponse()->addHeader( $this->getResponse()->addHeader(

View File

@ -45,11 +45,12 @@ use SilverStripe\View\SSViewer;
* Subclasses of ContentController are generally instantiated by ModelAsController; this will create * Subclasses of ContentController are generally instantiated by ModelAsController; this will create
* a controller based on the URLSegment action variable, by looking in the SiteTree table. * a controller based on the URLSegment action variable, by looking in the SiteTree table.
* *
* @template T of SiteTree
*/ */
class ContentController extends Controller class ContentController extends Controller
{ {
/** /**
* @var SiteTree * @var T
*/ */
protected $dataRecord; protected $dataRecord;
@ -71,7 +72,7 @@ class ContentController extends Controller
* The ContentController will take the URLSegment parameter from the URL and use that to look * The ContentController will take the URLSegment parameter from the URL and use that to look
* up a SiteTree record. * up a SiteTree record.
* *
* @param SiteTree $dataRecord * @param T|null $dataRecord
*/ */
public function __construct($dataRecord = null) public function __construct($dataRecord = null)
{ {
@ -110,7 +111,7 @@ class ContentController extends Controller
* Return the children of a given page. The parent reference can either be a page link or an ID. * Return the children of a given page. The parent reference can either be a page link or an ID.
* *
* @param string|int $parentRef * @param string|int $parentRef
* @return SS_List * @return SS_List<SiteTree>
*/ */
public function ChildrenOf($parentRef) public function ChildrenOf($parentRef)
{ {
@ -188,7 +189,6 @@ class ContentController extends Controller
*/ */
public function handleRequest(HTTPRequest $request): HTTPResponse public function handleRequest(HTTPRequest $request): HTTPResponse
{ {
/** @var SiteTree $child */
$child = null; $child = null;
$action = $request->param('Action'); $action = $request->param('Action');
@ -243,6 +243,7 @@ class ContentController extends Controller
/** /**
* Returns the associated database record * Returns the associated database record
* @return T
*/ */
public function data() public function data()
{ {
@ -254,7 +255,7 @@ class ContentController extends Controller
/** /**
* Returns a fixed navigation menu of the given level. * Returns a fixed navigation menu of the given level.
* @param int $level Menu level to return. * @param int $level Menu level to return.
* @return ArrayList * @return ArrayList<SiteTree>
*/ */
public function getMenu($level = 1) public function getMenu($level = 1)
{ {
@ -284,7 +285,6 @@ class ContentController extends Controller
// We might need to create a show in menu permission // We might need to create a show in menu permission
if (isset($result)) { if (isset($result)) {
foreach ($result as $page) { foreach ($result as $page) {
/** @var SiteTree $page */
if ($page->canView()) { if ($page->canView()) {
$visible[] = $page; $visible[] = $page;
} }
@ -294,6 +294,9 @@ class ContentController extends Controller
return new ArrayList($visible); return new ArrayList($visible);
} }
/**
* @return ArrayList<SiteTree>
*/
public function Menu($level) public function Menu($level)
{ {
return $this->getMenu($level); return $this->getMenu($level);

View File

@ -2,9 +2,13 @@
namespace SilverStripe\CMS\Controllers; namespace SilverStripe\CMS\Controllers;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\CMS\Controllers\CMSMain; use SilverStripe\CMS\Controllers\CMSMain;
use SilverStripe\Core\Extension; use SilverStripe\Core\Extension;
/**
* @extends Extension<LeftAndMain>
*/
class LeftAndMainBatchActionsExtension extends Extension class LeftAndMainBatchActionsExtension extends Extension
{ {
public function updateBatchActionsForm(&$form) public function updateBatchActionsForm(&$form)

View File

@ -5,6 +5,7 @@ namespace SilverStripe\CMS\Controllers;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException; use Psr\SimpleCache\InvalidArgumentException;
use ReflectionException; use ReflectionException;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Core\ClassInfo; use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
@ -16,10 +17,11 @@ use SilverStripe\View\Requirements;
/** /**
* Extension to include custom page icons * Extension to include custom page icons
*
* @extends Extension<LeftAndMain>
*/ */
class LeftAndMainPageIconsExtension extends Extension implements Flushable class LeftAndMainPageIconsExtension extends Extension implements Flushable
{ {
/** /**
* @throws InvalidArgumentException * @throws InvalidArgumentException
* @throws ReflectionException * @throws ReflectionException

View File

@ -123,7 +123,6 @@ class ModelAsController extends Controller implements NestedController
if (SiteTree::config()->get('nested_urls')) { if (SiteTree::config()->get('nested_urls')) {
$conditions[] = [sprintf('"%s"."ParentID"', $tableName) => 0]; $conditions[] = [sprintf('"%s"."ParentID"', $tableName) => 0];
} }
/** @var SiteTree $sitetree */
$sitetree = DataObject::get_one(SiteTree::class, $conditions); $sitetree = DataObject::get_one(SiteTree::class, $conditions);
if (!$sitetree) { if (!$sitetree) {

View File

@ -10,9 +10,11 @@ use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Core\Extension; use SilverStripe\Core\Extension;
/**
* @extends Extension<ContentController|ModelAsController>
*/
class OldPageRedirector extends Extension class OldPageRedirector extends Extension
{ {
/** /**
* On every URL that generates a 404, we'll capture it here and see if we can * On every URL that generates a 404, we'll capture it here and see if we can
* find an old URL that it should be redirecting to. * find an old URL that it should be redirecting to.
@ -75,7 +77,6 @@ class OldPageRedirector extends Extension
'ParentID' => is_numeric($parent) ? $parent : $parent->ID, 'ParentID' => is_numeric($parent) ? $parent : $parent->ID,
]); ]);
} }
/** @var SiteTree $page */
$page = $pages->first(); $page = $pages->first();
if (!$page) { if (!$page) {
// If we haven't found a candidate, lets resort to finding an old page with this URL segment // If we haven't found a candidate, lets resort to finding an old page with this URL segment

View File

@ -9,7 +9,8 @@ use SilverStripe\Forms\Form;
/** /**
* Decorates ModalController with insert internal link * Decorates ModalController with insert internal link
* @see ModalController *
* @extends Extension<ModalController>
*/ */
class InternalLinkModalExtension extends Extension class InternalLinkModalExtension extends Extension
{ {
@ -22,17 +23,6 @@ class InternalLinkModalExtension extends Extension
'editorAnchorLink', 'editorAnchorLink',
]; ];
/**
* @return ModalController
*/
public function getOwner()
{
/** @var ModalController $owner */
$owner = $this->owner;
return $owner;
}
/** /**
* Form for inserting internal link pages * Form for inserting internal link pages
* *

View File

@ -120,7 +120,6 @@ class RedirectorPage extends Page
} }
// Check internal redirect // Check internal redirect
/** @var SiteTree $linkTo */
$linkTo = $this->LinkToID ? SiteTree::get()->byID($this->LinkToID) : null; $linkTo = $this->LinkToID ? SiteTree::get()->byID($this->LinkToID) : null;
if (empty($linkTo)) { if (empty($linkTo)) {

View File

@ -7,6 +7,8 @@ use SilverStripe\Control\HTTPResponse_Exception;
/** /**
* Controller for the {@link RedirectorPage}. * Controller for the {@link RedirectorPage}.
*
* @extends PageController<RedirectorPage>
*/ */
class RedirectorPageController extends PageController class RedirectorPageController extends PageController
{ {
@ -26,7 +28,6 @@ class RedirectorPageController extends PageController
*/ */
public function index(HTTPRequest $request) public function index(HTTPRequest $request)
{ {
/** @var RedirectorPage $page */
$page = $this->data(); $page = $this->data();
// Redirect if we can // Redirect if we can

View File

@ -608,7 +608,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
return null; // There were no suitable matches at all. return null; // There were no suitable matches at all.
} }
/** @var SiteTree $page */
$link = Convert::raw2att($page->Link()); $link = Convert::raw2att($page->Link());
if ($content) { if ($content) {
@ -886,12 +885,10 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
*/ */
public function duplicateWithChildren() public function duplicateWithChildren()
{ {
/** @var SiteTree $clone */
$clone = $this->duplicate(); $clone = $this->duplicate();
$children = $this->AllChildren(); $children = $this->AllChildren();
if ($children) { if ($children) {
/** @var SiteTree $child */
$sort = 0; $sort = 0;
foreach ($children as $child) { foreach ($children as $child) {
$childClone = method_exists($child, 'duplicateWithChildren') $childClone = method_exists($child, 'duplicateWithChildren')
@ -914,7 +911,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
*/ */
public function duplicateAsChild($id) public function duplicateAsChild($id)
{ {
/** @var SiteTree $newSiteTree */
$newSiteTree = $this->duplicate(); $newSiteTree = $this->duplicate();
$newSiteTree->ParentID = $id; $newSiteTree->ParentID = $id;
$newSiteTree->Sort = 0; $newSiteTree->Sort = 0;
@ -950,7 +946,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
* @param boolean|string $stopAtPageType ClassName of a page to stop the upwards traversal. * @param boolean|string $stopAtPageType ClassName of a page to stop the upwards traversal.
* @param boolean $showHidden Include pages marked with the attribute ShowInMenus = 0 * @param boolean $showHidden Include pages marked with the attribute ShowInMenus = 0
* *
* @return ArrayList * @return ArrayList<SiteTree>
*/ */
public function getBreadcrumbItems($maxDepth = 20, $stopAtPageType = false, $showHidden = false) public function getBreadcrumbItems($maxDepth = 20, $stopAtPageType = false, $showHidden = false)
{ {
@ -1416,7 +1412,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
if (eval("return $condition;")) { if (eval("return $condition;")) {
$collator[] = $item; $collator[] = $item;
} }
/** @var SiteTree $item */
$item->collateDescendants($condition, $collator); $item->collateDescendants($condition, $collator);
} }
return true; return true;
@ -1768,7 +1763,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
// If deleting this page, delete all its children. // If deleting this page, delete all its children.
if ($this->isInDB() && SiteTree::config()->get('enforce_strict_hierarchy')) { if ($this->isInDB() && SiteTree::config()->get('enforce_strict_hierarchy')) {
foreach ($this->AllChildren() as $child) { foreach ($this->AllChildren() as $child) {
/** @var SiteTree $child */
$child->delete(); $child->delete();
} }
} }
@ -1966,7 +1960,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
/** /**
* Get the back-link tracking objects that link to this page * Get the back-link tracking objects that link to this page
* *
* @return ArrayList|DataObject[] * @return ArrayList<DataObject>
*/ */
public function BackLinkTracking() public function BackLinkTracking()
{ {
@ -2007,7 +2001,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
* Returns the pages that depend on this page. This includes virtual pages, pages that link to it, etc. * Returns the pages that depend on this page. This includes virtual pages, pages that link to it, etc.
* *
* @param bool $includeVirtuals Set to false to exlcude virtual pages. * @param bool $includeVirtuals Set to false to exlcude virtual pages.
* @return ArrayList|SiteTree[] * @return ArrayList<SiteTree>
*/ */
public function DependentPages($includeVirtuals = true) public function DependentPages($includeVirtuals = true)
{ {
@ -2057,7 +2051,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
/** /**
* Return all virtual pages that link to this page. * Return all virtual pages that link to this page.
* *
* @return DataList * @return DataList<SiteTree>
*/ */
public function VirtualPages() public function VirtualPages()
{ {
@ -2104,7 +2098,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
false, false,
$dependentPages $dependentPages
); );
/** @var GridFieldDataColumns $dataColumns */
$dataColumns = $dependentTable->getConfig()->getComponentByType(GridFieldDataColumns::class); $dataColumns = $dependentTable->getConfig()->getComponentByType(GridFieldDataColumns::class);
$dataColumns $dataColumns
->setDisplayFields($dependentColumns) ->setDisplayFields($dependentColumns)
@ -3333,7 +3326,6 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
$this->flushCache(); $this->flushCache();
// Need to mark pages depending to this one as broken // Need to mark pages depending to this one as broken
/** @var Page $page */
foreach ($this->DependentPages() as $page) { foreach ($this->DependentPages() as $page) {
// Update sync link tracking // Update sync link tracking
$page->syncLinkTracking(); $page->syncLinkTracking();

View File

@ -7,6 +7,9 @@ use SilverStripe\Security\Member;
/** /**
* Plug-ins for additional functionality in your SiteTree classes. * Plug-ins for additional functionality in your SiteTree classes.
*
* @template T of SiteTree
* @extends DataExtension<T>
*/ */
abstract class SiteTreeExtension extends DataExtension abstract class SiteTreeExtension extends DataExtension
{ {

View File

@ -28,6 +28,8 @@ use SilverStripe\View\Parsers\HTMLValue;
* *
* @property DataObject|SiteTreeLinkTracking $owner * @property DataObject|SiteTreeLinkTracking $owner
* @method ManyManyThroughList<SiteTree> LinkTracking() * @method ManyManyThroughList<SiteTree> LinkTracking()
*
* @extends DataExtension<DataObject>
*/ */
class SiteTreeLinkTracking extends DataExtension class SiteTreeLinkTracking extends DataExtension
{ {

View File

@ -61,7 +61,6 @@ class SiteTreeLinkTracking_Parser
$matches = []; $matches = [];
if (preg_match('/\[sitetree_link(?:\s*|%20|,)?id=(?<id>[0-9]+)\](#(?<anchor>.*))?/i', $href ?? '', $matches)) { if (preg_match('/\[sitetree_link(?:\s*|%20|,)?id=(?<id>[0-9]+)\](#(?<anchor>.*))?/i', $href ?? '', $matches)) {
// Check if page link is broken // Check if page link is broken
/** @var SiteTree $page */
$page = DataObject::get_by_id(SiteTree::class, $matches['id']); $page = DataObject::get_by_id(SiteTree::class, $matches['id']);
if (!$page) { if (!$page) {
// Page doesn't exist. // Page doesn't exist.

View File

@ -9,7 +9,6 @@ use SilverStripe\Reports\Report;
class EmptyPagesReport extends Report class EmptyPagesReport extends Report
{ {
public function title() public function title()
{ {
return _t(__CLASS__.'.EMPTYPAGES', "Pages without content"); return _t(__CLASS__.'.EMPTYPAGES', "Pages without content");
@ -29,7 +28,7 @@ class EmptyPagesReport extends Report
* Gets the source records * Gets the source records
* *
* @param array $params * @param array $params
* @return DataList * @return DataList<SiteTree>
*/ */
public function sourceRecords($params = null) public function sourceRecords($params = null)
{ {

View File

@ -2,6 +2,7 @@
namespace SilverStripe\CMS\Search; namespace SilverStripe\CMS\Search;
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Extension; use SilverStripe\Core\Extension;
use SilverStripe\Forms\TextField; use SilverStripe\Forms\TextField;
@ -12,6 +13,8 @@ use SilverStripe\ORM\Search\FulltextSearchable;
/** /**
* Extension to provide a search interface when applied to ContentController * Extension to provide a search interface when applied to ContentController
*
* @extends Extension<ContentController>
*/ */
class ContentControllerSearchExtension extends Extension class ContentControllerSearchExtension extends Extension
{ {