Situation:
I'm developing a package for Concrete 5 Version 5.6.3.1.
The problem:
When deleting an already published block from the frontend (like any
user does), the corresponding row in the DB-table isn't deleted.
When deleting the block without publishing, it works.
Here's my controller
class PcShooterChShowSomeThingsBlockController extends Concrete5_Controller_Block_Content {
protected $btName = "Show Some Things";
protected $btTable = 'btPcShooterChShowSomeThings';
protected $btInterfaceWidth = 500;
protected $btInterfaceHeight = 400;
protected $btWrapperClass = 'ccm-ui';
//...
public $pkgHandle = 'pc_shooter_ch_show_some_things';
//...
/**
* --------------- Overrides ----------------------
*/
public function delete() {
$db = Loader::db();
//Log::addEntry('DELETE FROM ' . $this->btTable . ' WHERE bID = ' . $this->bID);
$db->Execute('DELETE FROM ' . $this->btTable . ' WHERE bID = ' . $this->bID);
parent::delete();
}
}
The block itself works well, the package too. It isn't My first package at all, also I develop block/packages as recommended by C5.
I start thinking, its a bug, but before I post something on C5, I'm interested to hear from other C5 developers...
In the forum of C5 it says, that overriding the Concrete5_Controller_Block_Content's delete-method helps.
Also I tried to call the parent::delete(); at the beginnig instead of the end, but no difference.
UPDATE
The parents delete method from the Concrete5_Library_BlockController:
/**
* Automatically run when a block is deleted. This removes the special data
* from the block's specific database table. If a block needs to do more
* than this this method should be overridden.
* #return $void
*/
public function delete() {
if ($this->bID > 0) {
if ($this->btTable) {
$ni = new BlockRecord($this->btTable);
$ni->bID = $this->bID;
$ni->Load('bID=' . $this->bID);
$ni->delete();
}
}
}
UPDATE 1
Cache settings print screen
And, maybe it helps, the db.xml
<?xml version="1.0"?>
<schema version="0.3">
<table name="btPcShooterChShowSomeThings">
<field name="bID" type="I">
<key />
<unsigned />
</field>
<field name="desc_true" type="I2">
</field>
<field name="block_css_style" type="C" size="255">
</field>
<field name="block_css_id" type="C" size="255">
</field>
<field name="block_css_class" type="C" size="255">
</field>
<field name="title_css_class" type="C" size="255">
</field>
<field name="desc_css_class" type="C" size="255">
</field>
</table>
</schema>
If you need any further infos or code, just tell me. I'd be glad to get some tips on this.
UPDATE 2
A uninstall/install of the package does not help neither.
UPDATE 3
When deleting an already published block from the frontend (like any
user does), the corresponding row in the DB-table isn't deleted
and no delete() method is firing, neither myne nor the parent's
So finally, I've got an answer from a developer of the C5-team:
Not a bug. Blocks still store their data so that they can be
reinstated in case a previous version of a page gets approved and
rolled back to. Block's will only call BlockController::delete() when
they no longer need to keep their data around.
For other C5 developers:
Go to Dashboard > System & Settings > Automated Jobs (under "Optimization") and run the job:
"Remove Old Page Versions"
The child's (or parent's) delete method is firing.
The block is deleted.
Thx to Andrew Embler from the C5-Team!
Related
I have broken FKs in my database and if I load an entity and ask for a related entity Doctrine will throw \Doctrine\ORM\EntityNotFoundException.
For the entity in question, I would prefer that where the FK is broken it would return NULL rather than throw an exception. This is because its within a Twig template that the exception occurs and I would prefer Twig to not have to have to handle the exception in this case.
The following is an example configuration.
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Foo\Click" table="clicks">
<id name="id" type="bigint" column="click_id">
<generator strategy="IDENTITY"/>
</id>
<!-- .. -->
<many-to-one field="visitor" target-entity="Foo\Visitor" fetch="LAZY">
<join-columns>
<join-column name="visitor_id" referenced-column-name="visitor_id"/>
</join-columns>
</many-to-one>
</entity>
<entity name="Foo\Visitor" table="visitors" read-only="true">
<id name="visitorId" type="integer" column="visitor_id">
<generator strategy="IDENTITY"/>
</id>
<!-- ... -->
<one-to-one field="firstClick" target-entity="Foo\Click" fetch="LAZY">
<join-columns>
<join-column name="click_id" referenced-column-name="click_id"/>
</join-columns>
</one-to-one>
</entity>
</doctrine-mapping>
The following is an example of expected results where the the click as a visitor ID, but the a visitor record does not exists with that ID. In this case, I would rather not have to wrap the logic in Try/Catch and instead have Click::getVisitor() return null;
<?php
$clickOne = $entityManager()->find(Foo\Click::class, 1);
$v = $clickOne->getVisitor();
if ($v !== null) {
echo $v->getId(); // may throw Doctrine\ORM\EntityNotFoundException
}
Is there a strategy for this with Doctrine?
Update: Added example configuration and code, and now I see the why this is not achievable with a simple Doctrine configuration.
EntityNotFoundException is thrown from Doctrine's proxy. So you can use EAGER loading method to get rid of proxies and get NULL instead of exception.
This is the strategy I have adopted based on the comment made by iainn.
<?php
class Parent
{
protected $child;
public function getChild()
{
if ($this->child instance of \Doctrine\ORM\Proxy\Proxy) {
try {
$this->child->__load();
} catch (\Doctrine\ORM\EntityNotFoundException $e) {
$this->child = null
}
}
return $this->child;
}
}
I am sure it is not recommended for your entities to interact directly with proxies. But I preferred this over calling a known method on the entity (which would also have the effect of loading it) because the intention of this code is clearer to the next developer who might read it.
I'm not sure if there are any side effects with interacting with the proxy like this.
I have followed the Joomla Docs tutorial on how to add ACL to my custom component.
While I had success to add the component wide permission management I am struggeling to get the item level ACL to work.
I am trying to implement an ACL for the table books. I have added an asset_id column there as described in the tutorial.
I added a file book.xml in admin/models/forms/ - this is the content:
<?xml version="1.0" encoding="utf-8"?>
<form>
<field name="asset_id" type="hidden" filter="unset" />
<field name="rules"
type="rules"
label="JFIELD_RULES_LABEL"
translate_label="false"
filter="rules"
validate="rules"
class="inputbox"
component="com_mytest"
section="book"
/>
</form>
This is how my access.xml looks like:
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_mytest">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
<action name="core.edit" title="JACTION_EDIT_BOOK" description="COM_MYTEST_ACCESS_EDIT_BOOK_DESC" />
<action name="core.delete" title="JACTION_DELETE_BOOK" description="COM_MYTEST_ACCESS_DELETE_BOOK_DESC" />
</section>
<section name="book">
<action name="core.edit" title="JACTION_EDIT_BOOK" description="COM_MYTEST_ACCESS_EDIT_BOOK_DESC" />
<action name="core.delete" title="JACTION_DELETE_BOOK" description="COM_MYTEST_ACCESS_DELETE_BOOK_DESC" />
</section>
</access>
In my JTable variant in admin/tables/mytest_books.php I have added this methods:
public function bind($array, $ignore = '')
{
if (isset($array['jform']) && isset($array['jform']['rules']) && is_array($array['jform']['rules']))
{
$rules = new JAccessRules($array['jform']['rules']);
$this->setRules($rules);
}
return parent::bind($array, $ignore);
}
protected function _getAssetName()
{
return 'com_mytest.book.'.(int) $this->id;
}
protected function _getAssetTitle()
{
return $this->name;
}
protected function _getAssetParentId()
{
$asset = JTable::getInstance('Asset');
$asset->loadByName('com_mytest');
return $asset->id;
}
As you might notice in the bind() method above I have to extract the rules array from with in the jform array. In all tutorials I saw they simply reference $array['rules'] and not $array['jform']['rules'].
Maybe this is my issue?
This is my book model admin/models/book.php:
public function getForm($data = array(), $loadData = true)
{
$form = $this->loadForm('com_mytest.book', 'book', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)){
return false;
}
return $form;
}
protected function loadFormData()
{
$data = JFactory::getApplication()->getUserState('com_mytest.edit.book.data', array());
if (empty($data))
{
$data = $this->getItem($this->_id);
}
return $data;
}
Here is what I added at the bottom in the book editing screen admin/views/book/tmpl/default.php:
<?php echo JHtml::_('sliders.start', 'permissions-sliders-'.$this->row->id, array('useCookie'=>1)); ?>
<?php echo JHtml::_('sliders.panel', JText::_('COM_MYTEST_FIELDSET_RULES'), 'access-rules'); ?>
<fieldset class="panelform">
<?php echo $this->form->getLabel('rules'); ?>
<?php echo $this->form->getInput('rules'); ?>
</fieldset>
<?php echo JHtml::_('sliders.end'); ?>
Here is what is working:
When I save a book after editing the book level ACL for a group the settings save correctly. My asset table looks good, showing entries like:
id | name | title | rules
198 | com_mytest.book.2 | The guide to something | {"core.edit":{"1":0,"6":1,"7":1,"2":0,"3":0,"4":1,"5":0,"10":0,"12":0,"8":0},"core.delete":{"1":0,"6":1,"7":0,"2":0,"3":0,"4":0,"5":0,"10":0,"12":0,"8":0}}
And yes, the book with ID 2 has 198 in the asset_id column.
Here is my problem
When I save the book ACL by setting Allowed for all actions for the Administrator user group the dialog shows Conflict beside the permission. Setting everything to Denied does not show this message.
For the Allowed case (and the Conflict-situation):
When I use a second browser to login as an Administrator user group user this condition always returns false (yes, $row->id does contain a valid ID):
$canEdit = JFactory::getUser()->authorise('core.edit',
'com_mytest.book.'.$row->id);
Can you help me solving this puzzle?
Thank you very much!
Are your book assets getting the correct parent id in the asset table?
Any time you use ACL when not using categories you need to be extremely careful about parenting. Usually you want to ensure that the items are getting the component as the parent.
This is something that is a bit messy in the classes, but you can look at com_modules and see how this can work.
A conflict situation exists when a group has a hard deny somewhere between the item and the the start of the branch. Usually that might be denied on a component but allowed for a category of that component, as one example. You can get into a conflict situation if your parenting is not done correctly.
I am trying to use Apache SOLR for indexing my Mysql Database. The aim is to have solr handle all user related searches.
I am indexing the data as a parent child relationship as demonstrated in the tutorial ( http://wiki.apache.org/solr/DataImportHandler#Using_delta-import_command )
Basically i am trying to search a forum discussion. Where all post titles are stored in the table called "adda_topic" while all replies are stored in "adda_discussion" (where the first mesage is the message/content for the first post)
Here is my data-config.xml file
<document name="forum_posts">
<entity name="forum_topics" pk="topic_id"
query="SELECT *, 'forum' AS type FROM adda_topic"
deltaImportQuery="SELECT *, 'forum' AS type FROM adda_topic WHERE topic_id = '${dataimporter.delta.topic_id}'"
deltaQuery="SELECT topic_id FROM adda_topic WHERE topic_start_date > '${dataimporter.last_index_time}' ">
<field column="topic_id" name="id"/>
<field column="topic_apt_id" name="apt_id"/>
<field column="topic_owner_id" name="owner_id"/>
<field column="type" name="type"/>
<field column="topic_name" name="title"/>
<field column="topic_start_date" name="created_date"/>
<field column="topic_filter_level" name="filter_level"/>
<entity name="discussion" pk="discussion_topic_id" transformer="HTMLStripTransformer"
query="SELECT * FROM adda_discussion WHERE discussion_topic_id = '${forum_topics.topic_id}'"
deltaQuery="SELECT discussion_topic_id FROM adda_discussion WHERE discussion_date > '${dataimporter.last_index_time}'"
parentDeltaQuery="SELECT topic_id FROM adda_topic WHERE topic_id = '${discussion.discussion_topic_id}'">
<field column="discussion_id" name="child_ids"/>
<field column="discussion_text" name="content" stripHTML="true"/>
</entity>
</entity>
</document>
as you can see. I am grouping the discussions under each title/topic. Ann all replies have the same topic_id as its foreign key.
The problem i am facing is that When i import the data. Only the first discussion is searchable. IF i search for text in any of the replies i do not get any results.
Am i doing this right ? some topics can have hundreds of replies to it. and none of the replies are getting indexed or stored at the moment.
How do i get the replies to be searchable as well ?
e.g. if this is sample data . .
Test topic name here
Original reply/discussion for post here
additional reply one
Another reply two.
In the above case . I am able to search for "Test topic name here" and "Original reply/discussion for post here"
But i get zero results when i search for "additional reply one" or "Another reply two"
Well i managed to fix it on my own. ( almost lost my sanity on this one )
Tried various combinations. finally interchanged the discussion entity with the topic entity. ( basically interchanged parent and child )
So i now index the topic entity for every discussion entity.
A kind of a weird approach, but it works.
here is the working config snippet. just in case it helps anyone in the future.
<entity name="discussion" pk="discussion_id" transformer="HTMLStripTransformer"
query="SELECT * FROM adda_discussion"
deltaImportQuery="SELECT * FROM adda_discussion WHERE discussion_id = '${dataimporter.delta.discussion_id}'"
deltaQuery="SELECT discussion_id FROM adda_discussion WHERE discussion_date > '${dataimporter.last_index_time}' ">
<field column="discussion_id" name="id" />
<field column="discussion_text" name="content" stripHTML="true"/>
<field column="discussion_date" name="created_date"/>
<entity name="topic" pk="topic_id"
query="SELECT
*, 'forum' AS type, CONCAT('forum-', topic_id) AS global_id
FROM adda_topic WHERE topic_id='${discussion.discussion_topic_id}'"
deltaQuery="SELECT topic_id FROM adda_topic WHERE topic_start_date > '${dataimporter.last_index_time}'"
parentDeltaQuery="SELECT discussion_topic_id FROM adda_discussion WHERE discussion_topic_id = '${topic.topic_id}'">
<field column="global_id" name="global_id" />
<field column="topic_id" name="parent_id"/>
<field column="topic_apt_id" name="apt_id"/>
<field column="topic_owner_id" name="owner_id"/>
<field column="type" name="type"/>
<field column="topic_name" name="title"/>
<field column="topic_filter_level" name="filter_level"/>
</entity>
</entity>
Another point to note is that i had to group all messages together having the same topic_id using solr grouping so that you get only one result per topic.
The docs really need to be improved, It does not mention much.
Hope this helps a wandering soul in the future. :)
I have a problem and I'm new to Joomla and K2, so any help will be highly appreciated.
I'm developing a simple joomla plugin based on Example K2 Plugin (http://getk2.org/extend/extensions/90-example-k2-plugin-for-developers).
What i'm trying to create is a K2 extension for Categories, so i'll be able to add extra content to categories. I already did a search and there is not plugin or extension to cover my needs for this project with Joomal 3.x.
For each category I set information in the backend as currency, language, country , etc. I added this fields to the backend via the xml file.
I have tried several ways, but I haven't been able to access this information on my k2 template. When i dump parameters I get the default value from the xml, but not the one already saved for the category.
So i'm being able to easily display the content with a plugin template but by defect the only function available for categories will be onK2CategoryDisplay, but what i'm trying to achieve here is to call the fields values from the K2 template, next to the title for example, or below a gallery.
I found this lines, but it only displays the default text saved on the xml file, and not the new content. If i'm not being clear, please let me know and i'll update this post. Thanks in advance.
$plugin = JPluginHelper::getPlugin('k2', 'categories');
$pluginParams = new JRegistry();
$pluginParams->loadString($plugin->params);
$param = $pluginParams->get('localCountry_cat');
var_dump($param);
Here is the categories.xml:
<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="k2" method="upgrade">
<name>Categories K2 Plugin</name>
<files>
<filename plugin="categories">categories.php</filename>
<folder>categories</folder>
</files>
<config>
<fields name="params">
<fieldset name="basic">
<field name="localCountry_cat" type="text" size="80" default="test" label="Country local name" description="" />
<field name="capital_cat" type="text" size="80" default="test" label="Capital" description="" />
<field name="languages_cat" type="text" size="80" default="test" label="Official Languages" description="" />
</fieldset>
</fields>
</config>
<!-- K2 backend field parameters -->
<fields group="category">
<field name="localCountry_cat" type="text" size="80" default="" label="Country local name" description="" />
<field name="capital_cat" type="text" size="80" default="" label="Capital" description="" />
<field name="languages_cat" type="text" size="80" default="" label="Official Languages" description="" />
</fields>
Here is the categories.php
// no direct access
defined('_JEXEC') or die('Restricted access');
// Load the K2 plugin API
JLoader::register('K2Plugin', JPATH_ADMINISTRATOR.DS.'components'.DS.'com_k2'.DS.'lib'.DS.'k2plugin.php');
class plgK2categories extends K2Plugin {
// Required global reference parameters
var $pluginName = 'categories';
var $pluginNameHumanReadable = 'Categories K2 Plugin';
var $plgCopyrightsStart = " "
var $plgCopyrightsEnd = " ";
function plgK2categories( & $subject, $params) {
parent::__construct($subject, $params);
}
function onK2CategoryDisplay( & $category, & $params, $limitstart) {
// API
$mainframe = JFactory::getApplication();
$document = JFactory::getDocument();
// ---------- Get plugin parameters ---------------
// Global plugin params
$plugin = JPluginHelper::getPlugin('k2', $this->pluginName);
$pluginGlobalParams = new JRegistry( $plugin->params );
// K2 Category plugin specific params
$pluginParams = new K2Parameter($category->plugins, '', $this->pluginName);
$local = $pluginParams->get('localCountry_cat');
$capital = $pluginParams->get('capital_cat');
$languages = $pluginParams->get('languages_cat');
$currency = $pluginParams->get('currency_cat');
// --------- Requirements -------
require_once(dirname(__FILE__).DS.$this->pluginName.DS.'includes'.DS.'helper.php');
// ---------- Fetch the template -------
ob_start();
$getTemplatePath = categoriesHelper::getTemplatePath($this->pluginName,'default.php');
$getTemplatePath = $getTemplatePath->file;
include($getTemplatePath);
$getTemplate = $this->plgCopyrightsStart.ob_get_contents().$this->plgCopyrightsEnd;
ob_end_clean();
// ----- Output -----
return $getTemplate;
}
} // END CLASS
I already solved it. It was easier than I thought, but took me a while to discover it. The lack of documentation for K2 and it's developers is a huge pain.
Retrieved from the database the information with $this->params->get('itemK2Plugins'), but also with: $this->category->plugins
<?php if($this->params->get('itemK2Plugins')): ?>
<?php
$array = json_decode($this->category->plugins, true);
foreach($array as $key => $value) {
$keys[$key] = $value;
}
$countryL = $keys['categorieslocalCountry_cat'];
$MottoL = $keys['categorieslocalMotto_cat'];
?>
<?php endif; ?>
If there is a different and correct way to do it, please let me know!
Thanks :)
I am writing an integration module for our product to go into any Joomla 1.6 page. I need some help with getting custom data (from the API) into the basic settings part but can't seem to find a way to get it.
If you look at the documentation for the creation of a module, the settings for your module you set up in an XML format. That leaves you to hard code any values or selections without any dynamic options whatsoever. Basically what I want to do is setup a very basic module that takes three basic properties:
URL (used to define the path to the API)
API key (The API key)
List selection (Connects to the API and gets list names from your account.)
The list selection would change for every user's API key naturally but because you setup the module with an XML file I see no way around the hard coding of list selection options.
Please tell me if you can build a dynamic <select> with options in a Joomla 1.6 module.
NOTE: I say 1.6 because there is a major difference between 1.5 and 1.6 development in Joomla.
Well after a hell of a struggle and no help here whatsoever I can finally say that I have done it. Here is the process for any googlers in the future:
To build a dynamic dropdown you have to do a bunch of thing right for it to be pulled together by Joomla finally.
Also remember to read the documentation carefully, This answer's methods are not contained in it but maybe someone will wake up and put it there someday.
So after inspection of how the 1.6 architecture puts module variables together using the XML build file here we go.
The XML will look something like this :
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" version="1.6.0" client="site">
<name>...</name>
<author>...</author>
<creationDate>April 2011</creationDate>
<copyright>Copyright (C) 2011 ... All rights reserved.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>...</authorEmail>
<authorUrl>...</authorUrl>
<version>1.6.0</version>
<description>
...
</description>
<files>
<filename module="mod_your_mod">mod_your_mod.php</filename>
<filename>helper.php</filename>
<filename>index.html</filename>
<folder>tmpl</folder>
<folder>elements</folder>
<folder>lib</folder>
</files>
<languages />
<help />
<config>
<fields name="params">
<fieldset name="basic">
<!-- Custom field, list selection from API -->
<!-- Path to module external parameters -->
<field addfieldpath="/modules/mod_your_mod/elements"
name="mod_your_mod_id_selection" <!-- Name of variable -->
type="lists" <!-- New variable type -->
default=""
label="Select lists"
description="This is the list selection, where you select the list a contact can subscribe to." />
</fieldset>
<fieldset
name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
description="JFIELD_ALT_MODULE_LAYOUT_DESC" />
<field
name="moduleclass_sfx"
type="text"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
description="COM_MODULES_FIELD_MODULECLASS_SFX_DESC" />
<field
name="cache"
type="list"
default="1"
label="COM_MODULES_FIELD_CACHING_LABEL"
description="COM_MODULES_FIELD_CACHING_DESC">
<option
value="1">JGLOBAL_USE_GLOBAL</option>
<option
value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="text"
default="900"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
description="COM_MODULES_FIELD_CACHE_TIME_DESC" />
<field
name="cachemode"
type="hidden"
default="itemid">
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>
So after following the Joomla way of implementing a module here and here, I added the new parameter variable type into the elements folder as lists.php, see the name is the same as the type you declared in the XML file.
The class inside of this file looks like this :
<?php
// No direct access
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
jimport('joomla.html.html');
//import the necessary class definition for formfield
jimport('joomla.form.formfield');
// Include API utility file
require_once(dirname(__FILE__) . '/../lib/your_api.php');
class JFormFieldLists extends JFormField
{
/**
* The form field type.
*
* #var string
* #since 1.6
*/
protected $type = 'lists'; //the form field type see the name is the same
/**
* Method to retrieve the lists that resides in your application using the API.
*
* #return array The field option objects.
* #since 1.6
*/
protected function getInput()
{
$options = array();
$attr = '';
$attr .= ' multiple="multiple"';
$attr .= ' style="width:220px;height:220px;"';
// Get the database instance
$db = JFactory::getDbo();
// Build the select query
$query = 'SELECT params FROM jos_modules'
. ' WHERE module="mod_your_mod"';
$db->setQuery($query);
$params = $db->loadObjectList();
// Decode the options to get thje api key and url
$options = json_decode($params[0]->params, true);
// Gracefully catch empty fields
if ( empty($options['api_key']) === true )
{
$tmp = JHtml::_(
'select.option',
0,
'No lists available, please add an API key'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
if ( empty($options['url']) === true )
{
$tmp = JHtml::_(
'select.option',
0,
'No lists available, please add the enterprise URL'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
// Create a new API utility class
$api = new APIClass(
$options['url'],
$options['api_key']
);
try
{
// Get the lists needed for subscription
$response = $api->getLists();
}
catch ( Exception $e )
{
$tmp = JHtml::_(
'select.option',
0,
'Could not connect to the API'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
$lists = array();
// Builds the options for the dropdown
foreach ( $response['data'] as $list )
{
// Build options object here
$tmp = JHtml::_(
'select.option',
$list['list_id'],
$list['list_name']
);
$lists[] = $tmp;
}
// The dropdown output
/* The name of the select box MUST be the same as in the XML file otherwise
* saving your selection using Joomla will NOT work. Also if you want to make it
* multiple selects don't forget the [].
*/
return JHTML::_(
'select.genericlist',
$lists,
'jform[params][mod_your_mod_id_selection][]',
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
}
?>
So you will know when everything is working because your selection of the drop down list, built by the API(hence completely dynamic), will save into the module database entry with the name of the select box which you can easily retrieve by calling:
$api_key = $params->get('api_key', '');
in your module file. In this case its called mod_your_mod.php.
I really hope that this helps you when defining customized parameters in the back end of your Joomla 1.6 modules. This allows for extreme customizations and integrates tightly with whatever application you like to use's API.
The only downside is that it might be slow, but using a bunch of checks it fails gracefully when the API is down or not pulling data through correctly. All in all a very unpleasant CMS to work with but that is only my opinion.
There is also a much simpler solution if your needs are basic: http://docs.joomla.org/SQL_form_field_type
There is an "sql" form field type:
<field name="title" type="sql" default="10" label="Select an article" query="SELECT id AS value, title FROM #__content" />
(I sympathize with your frustration - the documentation is terrible, scattered and hard to find)