The Joomla! Forum ™



Forum rules


Please use the mailing list here: http://groups.google.com/group/joomla-dev-general rather than this forum.



Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: accessing subcontrollers
PostPosted: Mon Jun 04, 2012 3:33 pm 
Joomla! Apprentice
Joomla! Apprentice

Joined: Tue Mar 29, 2011 11:14 am
Posts: 14
Hi,

I have a problem to access subcontrollers in the administration menu.
My Extension has two subcontrollers: one for "sportactivities" which is a list of activities and a controller for sportmember (sportteilnehmer) which shows the member of a acitivty. I mentioned both because the sportteilnehmer controller works fine.

The structure is the following:
[administration]
[components]
[com_sportactivities]
[controller]
sportactivities.php
sportteilnehmer.php
[view]
[sportactivities]
sportactivities.php
[sportteilnehmer]
sportteilnehmer.php
controller.php

In my controller I load the sportacitivites view. When I click on Delete I expect the following to happen:
1.) show me a message when no activity is selected
2.) or run the function sportactivities.removeActivity

But when I click the Delecte Button in the Toolbar nothing is happen. Even 1.) is not happening.

Here is the code if needed:
controller:
Code:
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.application.component.controller');
/**
 *
 * @package    Joomla.Tutorials
 * @subpackage Components
 */
class sportactivitiesController extends JController
{
   /**
    * constructor (registers additional tasks to methods)
    * @return void
    */
   function __construct()
   {
      parent::__construct();

      // Register Extra tasks
      //$this->registerTask('add', 'edit');
   }


   function display($cachable = false)
   {
      // set default view if not set
    JRequest::setVar('view', JRequest::getCmd('view', 'sportactivities'));
       
      // call parent behavior
      parent::display($cachable);
   }


}


sportactivity subcontroller:
Code:
defined('_JEXEC') or die('Restricted access');
 
// import Joomla controlleradmin library
jimport('joomla.application.component.controlleradmin');
 
/**
 * Sportactivities Controller
 */
class sportactivitiesControllersportactivities extends JControllerAdmin
{
   /**
    * save a record (and redirect to main page)
    * @return void
    */
   function save()
   {
      $model = $this->getModel('sport');

      if ($model->store($post)) {
         $msg = JText::_( 'Greeting Saved!' );
      } else {
         $msg = JText::_( 'Error Saving Greeting' );
      }

      // Check the table in so it can be edited.... we are done with it anyway
      $this->setRedirect( 'index.php?option=com_sportactivities', $msg );
   }

   /**
    * remove record(s)
    * @return void
    */
   function removeActivity()
   {
   die("Activitiy");
      $this->setRedirect( 'index.php?option=com_sportactivities', "TEST" );
      
      $modelTeilnehmer = $this->getModel('sportteilnehmer');

      $model = $this->getModel('Sportactivities');
      if(!$model->delete($modelTeilnehmer)) {
         $msg = JText::_( 'ERROR DELETE SPORTACTIVITY' );
      } else {
         $msg = JText::_( 'SUCCESS DELETE SPORTACTIVITY' );
      }

      $this->setRedirect( 'index.php?option=com_sportactivities', $msg );
   }

  function removeAllOld() {
  die("allOdd");
      $modelTeilnehmer = $this->getModel('sportteilnehmer');
      $model = $this->getModel('Sportactivities');

      if(!$model->deleteAllOld($modelTeilnehmer)) {
         $msg = JText::_( 'ERROR DELETE SPORTACTIVITY' );
      } else {
         $msg = JText::_( 'SUCCESS DELETE MEMBER' );
      }

      $this->setRedirect( 'index.php?option=com_sportactivities', $msg );
   
  }
   

}


sportactivity view:
Code:
defined('_JEXEC') or die('Restricted access');
 
// import Joomla view library
jimport('joomla.application.component.view');
 
/**
 * HelloWorlds View
 */
class sportactivitiesViewsportactivities extends JView
{
   /**
    * display method of Hello view
    * @return void
    **/
   function display($tpl = null)
   {

      // Get data from the model
      //$items = $this->get('Items');
      $items      =& $this->get('data');
      $pagination = $this->get('Pagination');
 
      // Check for errors.
      if (count($errors = $this->get('Errors')))
      {
         JError::raiseError(500, implode('<br />', $errors));
         return false;
      }
      // Assign data to the view
      $this->items = $items;
      $this->pagination = $pagination;
 
      // Set the toolbar
      $this->addToolBar();
 
      // Display the template
      parent::display($tpl);
 
      // Set the document
      $this->setDocument();
                  
   }
 
   /**
    * Setting the toolbar
    */
   protected function addToolBar()
   {
      JToolBarHelper::title(JText::_( 'Sportactivities manager' ), 'generic.png');
      JToolBarHelper::deleteList(JText::_( 'Delete sportactivity'), 'sportactivities.removeActivity');
      JToolBarHelper::deleteList(JText::_( 'Delete all odd'), 'sportactivities.removeAllOld');
      
   }
   /**
    * Method to set up the document properties
    *
    * @return void
    */
   protected function setDocument()
   {
      $document = JFactory::getDocument();
      //$document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
   }   
}


Does anyone see what is wrong?
He does not load the subcontroller. I have tried it several hours with no result.

Thanks for help!!


Top
 Profile  
 
PostPosted: Mon Jun 04, 2012 3:52 pm 
Joomla! Explorer
Joomla! Explorer

Joined: Fri Nov 11, 2011 9:43 pm
Posts: 435
Location: Chicago, IL
Code:
   die("Activitiy");


Wouldn't the die() methods in your controller stop all HTML rendering in the remove methods? Also, Joomla has the built in means to add, edit and remove table entries; any reason you're not using these?


Top
 Profile  
 
PostPosted: Mon Jun 04, 2012 4:05 pm 
Joomla! Apprentice
Joomla! Apprentice

Joined: Tue Mar 29, 2011 11:14 am
Posts: 14
You are right, I should see nothing but "Activitiy" because of the die and I would be happy if I would see this ;)
But the controller does NOT show me the die, that is my problem.

I have 2 delete options, perhaps you are right, the first one I could use the Joomla default (in the controller, the model has to delete datas in several tables and needed to be override), but that should not be the problem.


Last edited by md22 on Mon Jun 04, 2012 6:18 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Jun 04, 2012 4:28 pm 
Joomla! Explorer
Joomla! Explorer

Joined: Fri Nov 11, 2011 9:43 pm
Posts: 435
Location: Chicago, IL
Are those tables linked with indexes or foreign keys? If so Joomla will automatically take care of their deletion.

Another thing I noticed was there wasn't a model file in your examples. For each sub-controller their needs to be a sub-model as well, which usually is just a container to call the static method in the helper file which handles the dirty work. Check the code out below for a declaration example.

Code:
class SportActivitiesModelRemoveActivity extends SportActivitiesModelSportActivities {
}


Top
 Profile  
 
PostPosted: Mon Jun 04, 2012 9:52 pm 
Joomla! Apprentice
Joomla! Apprentice

Joined: Tue Mar 29, 2011 11:14 am
Posts: 14
Thanks for the hint with the Foreign Key. I will test it.

Of course do I have model files for each subcontroller. But I only listet the important files above.

sportactivity model (with just one example function for a quick reading):
Code:
defined('_JEXEC') or die('Restricted access');

// import the Joomla modellist library
jimport('joomla.application.component.modellist');

class sportactivitiesModelsportactivities extends JModelList
{
   /**
    * Constructor that retrieves the ID from the request
    *
    * @access   public
    * @return   void
    */
   function __construct()
   {
      parent::__construct();

      $array = JRequest::getVar('cid',  0, '', 'array');
      $this->setId((int)$array[0]);
   }

   function deleteAllOld($modelTeilnehmer)
   {
      $db =& JFactory::getDBO();

      $query = 'SELECT id FROM #__sport where datum < NOW() ORDER BY datum';
      $db->setQuery( $query );
      $cids = $db->loadAssocList();
 
      $row =& $this->getTable('sport');

      if (count( $cids )) {
         foreach($cids as $cid) {
            if (!$row->delete( $cid['id'] )) {
               $this->setError( $row->getErrorMsg() );
               return false;
            } else
         
          {
          //Wenn löschen der Aktivität erfolgreich lösche Teilnehmer
          $Teilnehmer = $modelTeilnehmer->fechtTeilnehmerById($cid['id']);
          foreach ($Teilnehmer as $teilnehmer) {
              if(!$modelTeilnehmer->deleteByID($teilnehmer->id)) {
                 $this->setError( 'ERROR DELETE MEMBER' );
              }
          }
        }
         }
      }
      return true;
   }

}


But I always thought that the model is called by the controller.

By the way, is JModelList the correct class?

I have tried the this things in the Toolbar in the view:
JToolBarHelper::deleteList('', 'sportactivities.delete', 'JTOOLBAR_DELETE');
and just
JToolBarHelper::deleteList();

I expected the message: "Please first make a selection from the list" when nothing is marked, or that the item is deleted. But the only thing that happen is, that the page reloads.


And: thanks for helping me bbolli!


Top
 Profile  
 
PostPosted: Tue Jun 05, 2012 4:02 pm 
Joomla! Explorer
Joomla! Explorer

Joined: Fri Nov 11, 2011 9:43 pm
Posts: 435
Location: Chicago, IL
I pasted in the Model and View classes for the list view based on the 2.5 Joomla Programming book with comments stripped out and generic names. In the view.html.php file there is a line:

Code:
JToolBarHelper::deleteList('', 'myitems.delete','JTOOLBAR_EMPTY_TRASH');


Which adds the delete functionality without a need to create a method. You'll notice in the model there is no reference to a delete method and there doesn't need to be one as it is part of the core.

Code:
      $bar = JToolBar::getInstance('toolbar');
      $bar->appendButton('Link', 'export', 'COM_MYEXAMPLE_TOOLBAR_CUSTOMDELETE',
         'index.php?option=com_joomprosubs&task=myitems.mydelete');


This line would add your custom functionality for deleting to the toolbar icons.

ModelList is correct for the list view, but it looks like you are missing some methods. On a side note, ModelAdmin is the extended Joomla class for the single or detailed view and has its own set of methods you need to call.

A big thing to remember is that 2.5 depreciated a LOT of 1.5 functionality which shored up security and cleaned up the core. A result of this maturing of the code base was many of the shortcuts developers used to insert hand rolled classes and code snippets no longer work.

You have to think of 2.5 as an all or nothing approach, and in your defense; Joomla's online tutorials for 2.5 dwarf in detail and scope to the new Joomla Programming book. Which I might add is the ONLY reason I am able to integrate into Joomla 2.5. :D

MODEL
Code:
defined('_JEXEC') or die;
jimport('joomla.application.component.modellist');

class MyExampleModelMyItems extends JModelList
{
   public function __construct($config = array())
   {
      if (empty($config['filter_fields'])) {
         $config['filter_fields'] = array(
            'id', 'a.id',
            'title', 'a.title',
            'alias', 'a.alias',
            'checked_out', 'a.checked_out',
            'checked_out_time', 'a.checked_out_time',
            'catid', 'a.catid', 'category_title',
            'published', 'a.published',
            'access', 'a.access', 'access_level',
            'created', 'a.created',
            'created_by', 'a.created_by',
            'publish_up', 'a.publish_up',
            'publish_down', 'a.publish_down',
            'group_title', 'g.title',
            'duration', 'a.duration'
         );
      }

      parent::__construct($config);
   }

   protected function populateState($ordering = null, $direction = null)
   {
      $app = JFactory::getApplication('administrator');
      $search = $this->getUserStateFromRequest($this->context.'.filter.search', 'filter_search');
      $this->setState('filter.search', $search);
      $accessId = $this->getUserStateFromRequest($this->context.'.filter.access', 'filter_access', null, 'int');
      $this->setState('filter.access', $accessId);
      $published = $this->getUserStateFromRequest($this->context.'.filter.state', 'filter_published', '', 'string');
      $this->setState('filter.state', $published);
      $categoryId = $this->getUserStateFromRequest($this->context.'.filter.category_id', 'filter_category_id', '');
      $this->setState('filter.category_id', $categoryId);
      $params = JComponentHelper::getParams('com_joomprosubs');
      $this->setState('params', $params);
      parent::populateState('a.title', 'asc');
   }

   protected function getStoreId($id = '')
   {
      // Compile the store id.
      $id.= ':' . $this->getState('filter.search');
      $id.= ':' . $this->getState('filter.access');
      $id.= ':' . $this->getState('filter.state');
      $id.= ':' . $this->getState('filter.category_id');

      return parent::getStoreId($id);
   }

   protected function getListQuery()
   {
      $db      = $this->getDbo();
      $query   = $db->getQuery(true);
      $query->select('a.*');
      $query->from($db->quoteName('#__joompro_subscriptions').' AS a');
      $query->select('uc.name AS editor');
      $query->join('LEFT', $db->quoteName('#__users').' AS uc ON uc.id=a.checked_out');
      $query->select('g.title AS group_title');
      $query->join('LEFT', $db->quoteName('#__usergroups').' AS g ON a.group_id = g.id');
      $query->select('c.title AS category_title');
      $query->join('LEFT', $db->quoteName('#__categories').' AS c ON c.id = a.catid');
      if ($access = $this->getState('filter.access')) {
         $query->where('a.access = '.(int) $access);
      }
      $published = $this->getState('filter.state');
      if (is_numeric($published)) {
         $query->where('a.published = '.(int) $published);
      } else if ($published === '') {
         $query->where('(a.published IN (0, 1))');
      }
      $categoryId = $this->getState('filter.category_id');
      if (is_numeric($categoryId)) {
         $query->where('a.catid = '.(int) $categoryId);
      }
      $search = $this->getState('filter.search');
      if (!empty($search)) {
         if (stripos($search, 'id:') === 0) {
            $query->where('a.id = '.(int) substr($search, 3));
         } else {
            $search = $db->Quote('%'.$db->getEscaped($search, true).'%');
            $query->where('(a.title LIKE '.$search.' OR a.alias LIKE '.$search.')');
         }
      }
      $orderCol   = $this->state->get('list.ordering');
      $orderDirn   = $this->state->get('list.direction');
      $query->order($db->getEscaped($orderCol.' '.$orderDirn));
      return $query;
   }
}


VIEW.HTML.PHP
Code:
defined('_JEXEC') or die;
jimport('joomla.application.component.view');

class MyExampleViewMyItems extends JView
{
   protected $items;
   protected $pagination;
   protected $state;

   /**
    * Display the view
    */
   public function display($tpl = null)
   {
      $this->state = $this->get('State');
      $this->items = $this->get('Items');
      $this->pagination = $this->get('Pagination');
      if (count($errors = $this->get('Errors'))) {
         JError::raiseError(500, implode("\n", $errors));
         return false;
      }
      $this->addToolbar();
      parent::display($tpl);
   }

   protected function addToolbar()
   {
      JLoader::register('MyExampleHelper', JPATH_COMPONENT.'/helpers/myexample.php');
      $state   = $this->get('State');
      $canDo   = MyExampleHelper::getActions($state->get('filter.category_id'));
      $user   = JFactory::getUser();
      JToolBarHelper::title(JText::_('COM_MYEXAMPLE_MANAGER_MYITEMS'), 'icon.png');
      if ($canDo->get('core.create')) {
         JToolBarHelper::addNew('myitem.add','JTOOLBAR_NEW');
      }
      if ($canDo->get('core.edit')) {
         JToolBarHelper::editList('myitem.edit','JTOOLBAR_EDIT');
      }

      // Add export toolbar
      $bar = JToolBar::getInstance('toolbar');
      $bar->appendButton('Link', 'export', 'COM_MYEXAMPLE_TOOLBAR_CUSTOMDELETE',
         'index.php?option=com_joomprosubs&task=myitems.mydelete');

      if ($canDo->get('core.edit.state')) {

         JToolBarHelper::divider();
         JToolBarHelper::publish('myitems.publish', 'JTOOLBAR_PUBLISH', true);
         JToolBarHelper::unpublish('myitems.unpublish', 'JTOOLBAR_UNPUBLISH', true);

         JToolBarHelper::divider();
         JToolBarHelper::archiveList('myitems.archive');
         JToolBarHelper::checkin('myitems.checkin');
      }
      if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) {
         JToolBarHelper::deleteList('', 'myitems.delete','JTOOLBAR_EMPTY_TRASH');
         JToolBarHelper::divider();
      } else if ($canDo->get('core.edit.state')) {
         JToolBarHelper::trash('myitems.trash','JTOOLBAR_TRASH');
         JToolBarHelper::divider();
      }
      if ($canDo->get('core.admin')) {
         JToolBarHelper::preferences('com_myexample');
         JToolBarHelper::divider();
      }

      JToolBarHelper::help('', '', JText::_('COM_MYEXAMPLE_MYITEMS_HELP_LINK'));
   }
}


I inserted this code snippet because it is VERY important to proper integration. There is a lot of navigation and management features which depend on database items having this foundation. When I write an extension, I always use this as the base for the table and add columns and fields needed for what I'm writing. Without these additional fields, integration won't work properly.

Again, if possible, spend the $30 bucks on the book which lays everything out for you!

http://www.amazon.com/Joomla-Programmin ... 013278081X

<b>SQL</b>
Code:
CREATE TABLE IF NOT EXISTS `#__myitems` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatic incrementing key field',
  `catid` int(11) NOT NULL DEFAULT '0' COMMENT 'Foreign key to #__categories table',
  `title` varchar(250) NOT NULL DEFAULT '' COMMENT 'Title of Subscription',
  `alias` varchar(255) NOT NULL DEFAULT '' COMMENT 'Alias value, used for SEF URLs',
  `description` text NOT NULL COMMENT 'Description (will be edited using editor)',
  `group_id` int(11) NOT NULL DEFAULT '0' COMMENT 'Foreign key to #__groups table',
  `duration` int(11) NOT NULL DEFAULT '0' COMMENT 'Number for days that subscription lasts',
  `published` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Published state (1=published, 0=unpublished, -2=trashed)',
  `checked_out` int(11) NOT NULL DEFAULT '0',
  `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `access` int(11) NOT NULL DEFAULT '1' COMMENT 'Used to control access to subscriptions',
  `params` text NOT NULL COMMENT 'For possible future use to add item-level parameters (JSON string format)',
  `language` char(7) NOT NULL DEFAULT '' COMMENT 'For possible future use to add language switching',
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `created_by` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Foreign key to #__users table for user who created this item',
  `created_by_alias` varchar(255) NOT NULL DEFAULT '',
  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified_by` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Foreign key to #__users table for user who modified this item',
  `publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Date to start publishing this item',
  `publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Date to stop publishing this item',
  PRIMARY KEY (`id`),
  KEY `idx_access` (`access`),
  KEY `idx_checkout` (`checked_out`),
  KEY `idx_published` (`published`),
  KEY `idx_catid` (`catid`),
  KEY `idx_createdby` (`created_by`),
  KEY `idx_language` (`language`)
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


Top
 Profile  
 
PostPosted: Wed Jul 25, 2012 9:39 pm 
Joomla! Apprentice
Joomla! Apprentice

Joined: Tue Mar 29, 2011 11:14 am
Posts: 14
It was a really long search, but I could fix the problem. I bought the book, it is good, but I found the problem by try and error and looking other components of joomla. And I learned to use the API and to understand the classes of Joomla.

The problem was in the default.php of the view which looked this way:
Code:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
 
// load tooltip behavior
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_sportactivities'); ?>" method="post" name="adminForm">
   <table class="adminlist">
      <thead><?php echo $this->loadTemplate('head');?></thead>
      <tfoot><?php echo $this->loadTemplate('foot');?></tfoot>
      <tbody><?php echo $this->loadTemplate('body');?></tbody>
   </table>
   <div>
    <input type="hidden" name="option" value="com_sportactivities" />
    <input type="hidden" name="task" value="" />
    <input type="hidden" name="boxchecked" value="0" />
    <input type="hidden" name="controller" value="sportactivities" />
    <?php echo JHtml::_('form.token'); ?>
   </div>   

<input type="hidden" name="option" value="com_sportactivities" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="controller" value="sportactivities" />   
</form>


As you could see there is a double entry for option, task, boxcheked and controller. That's all.
And I hade to check that there is no little error in the subcontroller.

Nevertheless thanks for your help!!


Top
 Profile  
 
PostPosted: Thu Jul 26, 2012 4:55 pm 
Joomla! Explorer
Joomla! Explorer

Joined: Fri Nov 11, 2011 9:43 pm
Posts: 435
Location: Chicago, IL
Glad you got it figured out md22!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 



Who is online

Users browsing this forum: rcarey and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group