• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Lack of interest Event Listeners to manipulate criteria in controllers

R

ragtek

Guest
#1
ATM it's not possible to manipulate the fetch criteria, that's why i have to overwrite the COMPLETE method.
for example:
PHP:
class Ragtek_SMT_ControllerPublic_Forum extends
    XFCP_Ragtek_SMT_ControllerPublic_Forum
 
{ public function actionIndex()
    {
// same code as in the parent actionIndex, only with  this addition:
 
$showOnlyMyThreads = $this->checkCookie();
...
if ($showOnlyMyThreads){
$threadFetchConditions['user_id'] = $visitor['user_id'];
}
}
 
}
What about sending the fetchConditions & controller as reference to an event, so we can manipulate them? ( i know this would add too many new event listeners, but i'm not sure if there's any other way for this.. :( )

it's the same problem with the memberlist ( http://xenforo.com/community/threads/banned-users-still-in-members-list.11898/ ).
if i would want to change the criteria
PHP:
        $criteria = array(
            'user_state' => 'valid'
        );
 
        // users for the member list
        $users = $userModel->getUsers($criteria, array(
            'join' => XenForo_Model_User::FETCH_USER_FULL,
            'perPage' => $usersPerPage,
            'page' => $page
        ));
i would need to copy the whole code and include it in my method.

what, if now a second add-on wants to manipulate here something too?


another similar problem are "save actions"
what if i need to save own fields for a existing dw?
ATM we have to do really ugly things.. (e.g. overwrite whole method, stop the redirect, grab the last id, fetch the data,..... see my thread in the dev. forum where i asked how to save own additional fields in the acp user edit form..)
 

xfrocks

Well-known member
#3
I worked around it this way

PHP:
MyAddOn_ControllerPublic_Forum extends XFCP_MyAddOn_ControllerPublic_Forum {
public function actionIndex() {
$GLOBALS['MyAddOn_ControllerPublic_Forum'] = $this;
return parent::actionIndex();
}

public function MyAddOn_actionIndex(MyAddOn_Model_Forum $forumModel, array $conditions, array &$fetchOptions)
{
// do something
}
}
PHP:
MyAddOn_Model_Forum extends XFCP_MyAddOn_Model_Forum {
public function getForums(array $conditions = array(), array $fetchOptions = array())
{
if (!empty($GLOBALS['MyAddOn_ControllerPublic_Forum'])) {
$GLOBALS['MyAddOn_ControllerPublic_Forum']->MyAddOn_actionIndex($this, $conditions, $fetchOptions);
}
return parent::getForums($conditions, $fetchOptions);
}
}
Hope this helps :)
 
R

ragtek

Guest
#4
thx seems to be at least a better workaround as mine...
hm, but this still also works only if all add-ons are coded by coders using this way....

e.g. you have 3 add-ons adding own thread fetch criteria, which are set by cookie,get & post params, how would you do this?:p

add-on1 : wants to set where thread.user_id = ?
add-on2 : wants to set where thread.type='team'
add-on3 : wants to set where thread.user_id not in (1,2,3,4,5)
( OK addon 1 +3 doesn't make sense together, but that's only a example:p
It would be too complicated to explain what i exactly have...)

they would work fine if you want a result from only 1 add-on, but i need a result from:

select thread.* from xf_thread
where
thread.user_id = x
AND
thread.type='team'
AND
thread.user_id not in (1,2,3,4,5)

this isn't possible.
i would need to create my own proxy class, which includes the whole logic of all 3 add-ons
and thats fine for own pages... but i couldn't release any of this add-on to others...

also it would be really hard to maintain.. :(
kier said that 1.1 wouldn't break many add-ons, but e.g. some search methods got some additional params and this results in several add-ons throwing
e.g
PHP:
Declaration of Ragtek_xxx should be compatible with that of XenForo_Model_Search::insertSearch()
...
Argument 8 passed to XenForo_Model_Search::insertSearch() must be an array, integer given, called in //Ragtek/SR/Model.php on line 53 and defined
and i don't want to know what problems we will have once 2.0 gets released
 

xfrocks

Well-known member
#5
thx seems to be at least a better workaround as mine...
hm, but this still also works only if all add-ons are coded by coders using this way....

e.g. you have 3 add-ons adding own thread fetch criteria, which are set by cookie,get & post params, how would you do this?:p

add-on1 : wants to set where thread.user_id = ?
add-on2 : wants to set where thread.type='team'
add-on3 : wants to set where thread.user_id not in (1,2,3,4,5)
( OK addon 1 +3 doesn't make sense together, but that's only a example:p
It would be too complicated to explain what i exactly have...)
No, they will all work together if you do it correctly (and other developers don't do anything silly)

For example, in MyAddOn_actionIndex, you should read input, filter, etc. whatever you want and then you set like

PHP:
$conditions['MyAddOn_type'] = "team";
And then in your MyAddOn_Model_Forum, you should override prepareXConditions too. In this example, you should do something like this

PHP:
public function prepareForumConditions(array $conditions, array &$fetchOptions){
$result = parent::prepareForumConditions($conditions, $fetchOptions);
$sqlConditions = array($result);

if (!empty($conditions['MyAddOn_type'])) {
// our condition is set
$sqlConditions[] = 'forum.type = ' . $this->_getDb()->quote($conditions['MyAddOn_type']);
}

// do some other conditions if you want

if (count($sqlConditions) > 1) {
// got more than one, must have some custom conditions...
return $this->getConditionsForClause($sqlConditions);
} else {
// nothing unusual, just return the parent result
return $result;
}
}
If all add-ons work this way, they will work together just fine :D
 
R

ragtek

Guest
#6
If anybody is interested, it seems that they are preparing a solution for this.

check the conversation controller;)
PHP:
..
    $conditions = $this->_getListConditions();
        $fetchOptions = $this->_getListFetchOptions();

..

    protected function _getListConditions()
    {
        $searchType = $this->_input->filterSingle('search_type', XenForo_Input::STRING);
        $searchUser = $this->_input->filterSingle('search_user', XenForo_Input::STRING);

        if ($searchUser && $user = $this->getModelFromCache('XenForo_Model_User')->getUserByName($searchUser))
        {
            $conditions = array(
                'search_type' => $searchType,
                'search_user' => $user['username'],
                'search_user_id' => $user['user_id'],
            );
        }
        else
        {
            $conditions = array(
                'search_type' => '',
                'search_user' => '',
            );
        }

        return $conditions;
    }

    protected function _getListFetchOptions()
    {
        return array(
            'page' => $this->_input->filterSingle('page', XenForo_Input::UINT),
            'perPage' => XenForo_Application::get('options')->discussionsPerPage
        );
    }