Hi,
Contao allows you to select an Article as a Content Element. To do this it does exactly what you are trying to do - get a list of articles into a select box.
The code for this is located in system/modules/core/dca/tl_content.php.
Here is the code which i've just taken from the file mentioned above:
Code:
'article' => array
(
'label' => &$GLOBALS['TL_LANG']['tl_content']['article'],
'exclude' => true,
'inputType' => 'select',
'options_callback' => array('tl_content', 'getArticles'),
'eval' => array('mandatory'=>true, 'chosen'=>true, 'submitOnChange'=>true),
'wizard' => array
(
array('tl_content', 'editArticle')
),
'sql' => "int(10) unsigned NOT NULL default '0'"
),
You see the 'options_callback' parameter passes a class name 'tl_content' and a method name 'getArticles'. This returns the list of articles to the select box.
This class is located in the same file, you can find it at the bottom. Here is the code for the class - I've only included the bit you need, you can see the whole thing by looking in the file I mentioned above:
Code:
class tl_content extends Backend
{
/**
* Import the back end user object
*/
public function __construct()
{
parent::__construct();
$this->import('BackendUser', 'User');
}
/**
* Get all articles and return them as array (article teaser)
* @param \DataContainer
* @return array
*/
public function getArticles(DataContainer $dc)
{
$arrPids = array();
$arrArticle = array();
$arrRoot = array();
$intPid = $dc->activeRecord->pid;
if (Input::get('act') == 'overrideAll')
{
$intPid = Input::get('id');
}
// Limit pages to the website root
$objArticle = $this->Database->prepare("SELECT pid FROM tl_article WHERE id=?")
->limit(1)
->execute($intPid);
if ($objArticle->numRows)
{
$objPage = PageModel::findWithDetails($objArticle->pid);
$arrRoot = $this->Database->getChildRecords($objPage->rootId, 'tl_page');
array_unshift($arrRoot, $objPage->rootId);
}
unset($objArticle);
// Limit pages to the user's pagemounts
if ($this->User->isAdmin)
{
$objArticle = $this->Database->execute("SELECT a.id, a.pid, a.title, a.inColumn, p.title AS parent FROM tl_article a LEFT JOIN tl_page p ON p.id=a.pid" . (!empty($arrRoot) ? " WHERE a.pid IN(". implode(',', array_map('intval', array_unique($arrRoot))) .")" : "") . " ORDER BY parent, a.sorting");
}
else
{
foreach ($this->User->pagemounts as $id)
{
if (!in_array($id, $arrRoot))
{
continue;
}
$arrPids[] = $id;
$arrPids = array_merge($arrPids, $this->Database->getChildRecords($id, 'tl_page'));
}
if (empty($arrPids))
{
return $arrArticle;
}
$objArticle = $this->Database->execute("SELECT a.id, a.pid, a.title, a.inColumn, p.title AS parent FROM tl_article a LEFT JOIN tl_page p ON p.id=a.pid WHERE a.pid IN(". implode(',', array_map('intval', array_unique($arrPids))) .") ORDER BY parent, a.sorting");
}
// Edit the result
if ($objArticle->numRows)
{
System::loadLanguageFile('tl_article');
while ($objArticle->next())
{
$key = $objArticle->parent . ' (ID ' . $objArticle->pid . ')';
$arrArticle[$key][$objArticle->id] = $objArticle->title . ' (' . ($GLOBALS['TL_LANG']['tl_article'][$objArticle->inColumn] ?: $objArticle->inColumn) . ', ID ' . $objArticle->id . ')';
}
}
return $arrArticle;
}
}
The code in that method fetches the articles. It does a few extra things too like checking that the user has access to the articles and the pages that the articles are placed on.
The end result is that it returns an array of articles to your field which are then listed in your select box.
The code formatting isn't great on this post, so i'd recommend you open up system/modules/core/dca/tl_content.php in your editor and have a look.
Note: If you're not using Contao 3, the file will be located in a different place - system/modules/backend/dca/tl_content.php
Bookmarks