/**
  * import helper
  *
  * @param array $_options
  * @param string|Tinebase_Model_ImportExportDefinition $_definition
  * @param Tinebase_Model_Filter_FilterGroup $_exportFilter
  * @throws Tinebase_Exception_NotFound
  * @return array
  */
 protected function _doImport(array $_options, $_definition, Tinebase_Model_Filter_FilterGroup $_exportFilter = NULL)
 {
     if (!$this->_importerClassName || !$this->_modelName) {
         throw new Tinebase_Exception_NotFound('No import class or model name given');
     }
     $definition = $_definition instanceof Tinebase_Model_ImportExportDefinition ? $_definition : Tinebase_ImportExportDefinition::getInstance()->getByName($_definition);
     $this->_instance = call_user_func_array($this->_importerClassName . '::createFromDefinition', array($definition, $_options));
     // export first
     if ($_exportFilter !== NULL && $this->_exporterClassName) {
         $exporter = new $this->_exporterClassName($_exportFilter, Tinebase_Core::getApplicationInstance($this->_modelName));
         $this->_filename = $exporter->generate();
     }
     // then import
     $result = $this->_instance->importFile($this->_filename);
     return $result;
 }
 /**
  * append relation filter
  * 
  * @param Crm_Model_LeadFilter $filter
  */
 protected function _appendRelationFilter($filter)
 {
     if (!Tinebase_Core::getPreference()->getValue(Tinebase_Preference::ADVANCED_SEARCH, false)) {
         return;
     }
     $relationsToSearchIn = array('Addressbook_Model_Contact', 'Sales_Model_Product', 'Tasks_Model_Task');
     $leadIds = array();
     foreach ($relationsToSearchIn as $relatedModel) {
         $filterModel = $relatedModel . 'Filter';
         $relatedFilter = new $filterModel(array(array('field' => 'query', 'operator' => 'contains', 'value' => $this->_value)));
         $relatedIds = Tinebase_Core::getApplicationInstance($relatedModel)->search($relatedFilter, NULL, FALSE, TRUE);
         $relationFilter = new Tinebase_Model_RelationFilter(array(array('field' => 'own_model', 'operator' => 'equals', 'value' => 'Crm_Model_Lead'), array('field' => 'related_model', 'operator' => 'equals', 'value' => $relatedModel), array('field' => 'related_id', 'operator' => 'in', 'value' => $relatedIds)));
         $leadIds = array_merge($leadIds, Tinebase_Relations::getInstance()->search($relationFilter, NULL)->own_id);
     }
     $filter->addFilter(new Tinebase_Model_Filter_Id('id', 'in', $leadIds));
 }
コード例 #3
0
 /**
  * the constructor
  * 
  * @param string $_path
  * @throws Sabre\DAV\Exception\NotFound
  */
 public function __construct($path)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Record path: ' . $path);
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . print_r(Sabre\DAV\URLUtil::splitPath($path), true));
     }
     try {
         list($appModel, $id) = Sabre\DAV\URLUtil::splitPath($path);
         list($appName, $records, $model) = explode('/', $appModel);
         $this->_record = Tinebase_Core::getApplicationInstance($appName, $model)->get($id);
     } catch (Tinebase_Exception_NotFound $tenf) {
         throw new Sabre\DAV\Exception\NotFound('Record ' . $path . ' not found');
     }
     $this->_appName = $appName;
     $this->_path = $path;
 }
コード例 #4
0
 /**
  * calls the handleEvent function in the controller of all enabled applications 
  *
  * @param  Tinebase_Event_Object  $_eventObject  the event object
  */
 public static function fireEvent(Tinebase_Event_Abstract $_eventObject)
 {
     self::$events[get_class($_eventObject)][$_eventObject->getId()] = $_eventObject;
     if (self::isDuplicateEvent($_eventObject)) {
         // do nothing
         return;
     }
     foreach (Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED) as $application) {
         try {
             $controller = Tinebase_Core::getApplicationInstance($application, NULL, TRUE);
         } catch (Tinebase_Exception_NotFound $e) {
             // application has no controller or is not useable at all
             continue;
         }
         if ($controller instanceof Tinebase_Event_Interface) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') calling eventhandler for event ' . get_class($_eventObject) . ' of application ' . (string) $application);
             }
             try {
                 $controller->handleEvent($_eventObject);
             } catch (Exception $e) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
                     Tinebase_Core::getLogger()->notice(__METHOD__ . ' (' . __LINE__ . ') ' . (string) $application . ' threw an exception: ' . $e->getMessage());
                 }
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                     Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') ' . $e->getTraceAsString());
                 }
             }
         }
     }
     // try custom user defined listeners
     try {
         if (@class_exists('CustomEventHooks')) {
             $methods = get_class_methods('CustomEventHooks');
             if (in_array('handleEvent', (array) $methods)) {
                 Tinebase_Core::getLogger()->info(__METHOD__ . ' (' . __LINE__ . ') ' . ' about to process user defined event hook for ' . get_class($_eventObject));
                 CustomEventHooks::handleEvent($_eventObject);
             }
         }
     } catch (Exception $e) {
         Tinebase_Core::getLogger()->info(__METHOD__ . ' (' . __LINE__ . ') ' . ' failed to process user defined event hook with message: ' . $e);
     }
     unset(self::$events[get_class($_eventObject)][$_eventObject->getId()]);
 }
コード例 #5
0
 /**
  * send pending alarms
  *
  * @param mixed $_eventName
  * @return void
  * 
  * @todo sort alarms (by model/...)?
  * @todo what to do about Tinebase_Model_Alarm::STATUS_FAILURE alarms?
  */
 public function sendPendingAlarms($_eventName)
 {
     $eventName = is_array($_eventName) ? $_eventName['eventName'] : $_eventName;
     $job = Tinebase_AsyncJob::getInstance()->startJob($eventName);
     if (!$job) {
         return;
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' No ' . $eventName . ' is running. Starting new one.');
     }
     try {
         // get all pending alarms
         $filter = new Tinebase_Model_AlarmFilter(array(array('field' => 'alarm_time', 'operator' => 'before', 'value' => Tinebase_DateTime::now()->subMinute(1)->get(Tinebase_Record_Abstract::ISO8601LONG)), array('field' => 'sent_status', 'operator' => 'equals', 'value' => Tinebase_Model_Alarm::STATUS_PENDING)));
         $limit = Tinebase_Config::getInstance()->get(Tinebase_Config::ALARMS_EACH_JOB, 100);
         $pagination = $limit > 0 ? new Tinebase_Model_Pagination(array('limit' => $limit)) : null;
         $alarms = $this->_backend->search($filter, $pagination);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Sending ' . count($alarms) . ' alarms (limit: ' . $limit . ').');
         }
         // loop alarms and call sendAlarm in controllers
         foreach ($alarms as $alarm) {
             list($appName, $i, $itemName) = explode('_', $alarm->model);
             $appController = Tinebase_Core::getApplicationInstance($appName, $itemName);
             if ($appController instanceof Tinebase_Controller_Alarm_Interface) {
                 $alarm->sent_time = Tinebase_DateTime::now();
                 try {
                     // NOTE: we set the status here, so controller can adopt the status itself
                     $alarm->sent_status = Tinebase_Model_Alarm::STATUS_SUCCESS;
                     $appController->sendAlarm($alarm);
                 } catch (Exception $e) {
                     Tinebase_Exception::log($e);
                     $alarm->sent_message = $e->getMessage();
                     $alarm->sent_status = Tinebase_Model_Alarm::STATUS_FAILURE;
                 }
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                     Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating alarm status: ' . $alarm->sent_status);
                 }
                 $this->update($alarm);
             }
         }
         $job = Tinebase_AsyncJob::getInstance()->finishJob($job);
     } catch (Exception $e) {
         // save new status 'failure'
         $job = Tinebase_AsyncJob::getInstance()->finishJob($job, Tinebase_Model_AsyncJob::STATUS_FAILURE, $e->getMessage());
         if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) {
             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Job failed: ' . $e->getMessage());
         }
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $e->getTraceAsString());
         }
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Job ' . $eventName . ' finished.');
     }
 }
コード例 #6
0
 /**
  * get default modelconfig methods
  *
  * @return array of Zend_Server_Method_Definition
  */
 protected static function _getModelConfigMethods()
 {
     // get all apps user has RUN right for
     $userApplications = Tinebase_Core::getUser()->getApplications();
     $definitions = array();
     foreach ($userApplications as $application) {
         try {
             $controller = Tinebase_Core::getApplicationInstance($application->name);
             $models = $controller->getModels();
             if (!$models) {
                 continue;
             }
         } catch (Exception $e) {
             Tinebase_Exception::log($e);
             continue;
         }
         foreach ($models as $model) {
             $config = $model::getConfiguration();
             if ($config && $config->exposeJsonApi) {
                 // TODO replace this with generic method
                 $simpleModelName = str_replace($application->name . '_Model_', '', $model);
                 $commonJsonApiMethods = array('get' => array('params' => array(new Zend_Server_Method_Parameter(array('type' => 'string', 'name' => 'id'))), 'help' => 'get one ' . $simpleModelName . ' identified by $id', 'plural' => false), 'search' => array('params' => array(new Zend_Server_Method_Parameter(array('type' => 'array', 'name' => 'filter')), new Zend_Server_Method_Parameter(array('type' => 'array', 'name' => 'paging'))), 'help' => 'Search for ' . $simpleModelName . 's matching given arguments', 'plural' => true), 'save' => array('params' => array(new Zend_Server_Method_Parameter(array('type' => 'array', 'name' => 'recordData'))), 'help' => 'Save ' . $simpleModelName . '', 'plural' => false), 'delete' => array('params' => array(new Zend_Server_Method_Parameter(array('type' => 'array', 'name' => 'ids'))), 'help' => 'Delete multiple ' . $simpleModelName . 's', 'plural' => true));
                 foreach ($commonJsonApiMethods as $name => $method) {
                     $key = $application->name . '.' . $name . $simpleModelName . ($method['plural'] ? 's' : '');
                     $appJsonFrontendClass = $application->name . '_Frontend_Json';
                     if (class_exists($appJsonFrontendClass)) {
                         $class = $appJsonFrontendClass;
                         $object = null;
                     } else {
                         $class = 'Tinebase_Frontend_Json_Generic';
                         $object = new Tinebase_Frontend_Json_Generic($application->name);
                     }
                     $definitions[$key] = new Zend_Server_Method_Definition(array('name' => $key, 'prototypes' => array(array('returnType' => 'array', 'parameters' => $method['params'])), 'methodHelp' => $method['help'], 'invokeArguments' => array(), 'object' => $object, 'callback' => array('type' => 'instance', 'class' => $class, 'method' => $name . $simpleModelName . ($method['plural'] ? 's' : ''))));
                 }
             }
         }
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Got MC definitions: ' . print_r(array_keys($definitions), true));
     }
     return $definitions;
 }
 /**
  * move records to container
  * 
  * @param string $targetContainerId
  * @param array  $filterData
  * @param string $applicationName
  * @param string $model
  * @return array
  */
 public function moveRecordsToContainer($targetContainerId, $filterData, $applicationName, $model)
 {
     $filterModel = $applicationName . '_Model_' . $model . 'Filter';
     $filter = new $filterModel(array());
     $filter->setFromArrayInUsersTimezone($filterData);
     $this->_longRunningRequest();
     $recordController = Tinebase_Core::getApplicationInstance($applicationName, $model);
     $result = $recordController->move($filter, $targetContainerId);
     return array('status' => 'success', 'results' => $result);
 }
コード例 #8
0
 /**
  * resolve foreign fields for records like user ids to users, etc.
  * 
  * @param Tinebase_Record_RecordSet $records
  * @param string $foreignRecordClassName
  * @param array $fields
  */
 protected static function _resolveForeignIdFields($records, $foreignRecordClassName, $fields)
 {
     $options = isset($fields['options']) || array_key_exists('options', $fields) ? $fields['options'] : array();
     $fields = isset($fields['fields']) || array_key_exists('fields', $fields) ? $fields['fields'] : $fields;
     $foreignIds = array();
     foreach ($fields as $field) {
         $foreignIds = array_unique(array_merge($foreignIds, $records->{$field}));
     }
     try {
         $controller = Tinebase_Core::getApplicationInstance($foreignRecordClassName);
     } catch (Tinebase_Exception_AccessDenied $tead) {
         if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
             Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' No right to access application of record ' . $foreignRecordClassName);
         }
         return;
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Fetching ' . $foreignRecordClassName . ' by id: ' . print_r($foreignIds, TRUE));
     }
     if ((isset($options['ignoreAcl']) || array_key_exists('ignoreAcl', $options)) && $options['ignoreAcl']) {
         // @todo make sure that second param of getMultiple() is $ignoreAcl
         $foreignRecords = $controller->getMultiple($foreignIds, TRUE);
     } else {
         $foreignRecords = $controller->getMultiple($foreignIds);
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Foreign records found: ' . print_r($foreignRecords->toArray(), TRUE));
     }
     if (count($foreignRecords) === 0) {
         return;
     }
     foreach ($records as $record) {
         foreach ($fields as $field) {
             if (is_scalar($record->{$field})) {
                 $idx = $foreignRecords->getIndexById($record->{$field});
                 if (isset($idx) && $idx !== FALSE) {
                     $record->{$field} = $foreignRecords[$idx];
                 } else {
                     switch ($foreignRecordClassName) {
                         case 'Tinebase_Model_User':
                         case 'Tinebase_Model_FullUser':
                             $record->{$field} = Tinebase_User::getInstance()->getNonExistentUser();
                             break;
                         default:
                             // skip
                     }
                 }
             }
         }
     }
 }
コード例 #9
0
 /**
  * get option setting string
  * 
  * @deprecated
  * @param Tinebase_Record_Interface $_record
  * @param string $_id
  * @param string $_label
  * @return string
  */
 public static function getOptionString($_record, $_label)
 {
     $controller = Tinebase_Core::getApplicationInstance($_record->getApplication());
     $settings = $controller->getConfigSettings();
     $idField = $_label . '_id';
     $option = $settings->getOptionById($_record->{$idField}, $_label . 's');
     $result = isset($option[$_label]) ? $option[$_label] : '';
     return $result;
 }
 /**
  * @param Sales_Model_ProductAggregate $productAggregate
  * @return null|Tinebase_Record_RecordSet
  * @throws Tinebase_Exception_AccessDenied
  * @throws Tinebase_Exception_NotFound
  */
 protected function _getProductAccountables(Sales_Model_ProductAggregate $productAggregate)
 {
     $json_attributes = $productAggregate->json_attributes;
     if (!is_array($json_attributes) || !isset($json_attributes['assignedAccountables'])) {
         return null;
     }
     $product = Sales_Controller_Product::getInstance()->get($productAggregate->product_id);
     if ($product->accountable == '') {
         return null;
     }
     $app = Tinebase_Core::getApplicationInstance($product->accountable, '');
     return $app->getMultiple($json_attributes['assignedAccountables']);
 }
コード例 #11
0
 /**
  * gets image info and data
  * 
  * @param   string $_application application which manages the image
  * @param   string $_identifier identifier of image/record
  * @param   string $_location optional additional identifier
  * @return  Tinebase_Model_Image
  * @throws  Tinebase_Exception_NotFound
  * @throws  Tinebase_Exception_UnexpectedValue
  */
 public function getImage($_application, $_identifier, $_location = '')
 {
     $appController = Tinebase_Core::getApplicationInstance($_application);
     if (!method_exists($appController, 'getImage')) {
         throw new Tinebase_Exception_NotFound("{$_application} has no getImage function.");
     }
     $image = $appController->getImage($_identifier, $_location);
     if (!$image instanceof Tinebase_Model_Image) {
         throw new Tinebase_Exception_UnexpectedValue("{$_application} returned invalid image.");
     }
     return $image;
 }
 /**
  * creates a new container
  * 
  * @todo allow to create personal folders only when in currents users own path
  * 
  * @param  array  $properties  properties for new container
  * @throws \Sabre\DAV\Exception\Forbidden
  * @return Tinebase_Model_Container
  */
 protected function _createContainer(array $properties)
 {
     if (count($this->_getPathParts()) !== 2) {
         throw new \Sabre\DAV\Exception\Forbidden('Permission denied to create directory ' . $properties['name']);
     }
     $containerType = Tinebase_Helper::array_value(1, $this->_getPathParts()) == Tinebase_Model_Container::TYPE_SHARED ? Tinebase_Model_Container::TYPE_SHARED : Tinebase_Model_Container::TYPE_PERSONAL;
     $newContainer = new Tinebase_Model_Container(array_merge($properties, array('type' => $containerType, 'backend' => 'Sql', 'application_id' => $this->_getApplication()->getId(), 'model' => Tinebase_Core::getApplicationInstance($this->_applicationName)->getDefaultModel())));
     try {
         $container = Tinebase_Container::getInstance()->addContainer($newContainer);
     } catch (Tinebase_Exception_AccessDenied $tead) {
         throw new \Sabre\DAV\Exception\Forbidden('Permission denied to create directory ' . $properties['name']);
     }
     return $container;
 }
コード例 #13
0
 /**
  * generates path for the record
  *
  * @param Tinebase_Record_Abstract $record
  * @param boolean $rebuildRecursively
  * @return Tinebase_Record_RecordSet
  *
  * TODO what about acl? the account who creates the path probably does not see all relations ...
  */
 public function generatePathForRecord(Tinebase_Record_Abstract $record, $rebuildRecursively = false)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Generate path for ' . get_class($record) . ' record with id ' . $record->getId());
     }
     $recordController = Tinebase_Core::getApplicationInstance(get_class($record));
     // if we rebuild recursively, dont do any tree operation, just rebuild the paths for the record and be done with it
     if (false === $rebuildRecursively) {
         // fetch full record + check acl
         $record = $recordController->get($record->getId());
         $currentPaths = Tinebase_Record_Path::getInstance()->getPathsForRecords($record);
     }
     $newPaths = new Tinebase_Record_RecordSet('Tinebase_Model_Path');
     // fetch all parent -> child relations and add to path
     $newPaths->merge($this->_getPathsOfRecord($record, $rebuildRecursively));
     if (method_exists($recordController, 'generatePathForRecord')) {
         $newPaths->merge($recordController->generatePathForRecord($record));
     }
     // if we rebuild recursively, dont do any tree operation, just rebuild the paths for the record and be done with it
     if (false === $rebuildRecursively) {
         //compare currentPaths with newPaths to find out if we need to make subtree updates
         //we should do this before the new paths of the current record have been persisted to DB!
         $currentShadowPathOffset = array();
         foreach ($currentPaths as $offset => $path) {
             $currentShadowPathOffset[$path->shadow_path] = $offset;
         }
         $newShadowPathOffset = array();
         foreach ($newPaths as $offset => $path) {
             $newShadowPathOffset[$path->shadow_path] = $offset;
         }
         $toDelete = array();
         $anyOldOffset = null;
         foreach ($currentShadowPathOffset as $shadowPath => $offset) {
             $anyOldOffset = $offset;
             // parent path has been deleted!
             if (false === isset($newShadowPathOffset[$shadowPath])) {
                 $toDelete[] = $shadowPath;
                 continue;
             }
             $currentPath = $currentPaths[$offset];
             $newPath = $newPaths[$newShadowPathOffset[$shadowPath]];
             // path changed (a title was updated or similar)
             if ($currentPath->path !== $newPath->path) {
                 // update ... set path = REPLACE(path, $currentPath->path, $newPath->path) where shadow_path LIKE '$shadowPath/%'
                 $this->_backend->replacePathForShadowPathTree($shadowPath, $currentPath->path, $newPath->path);
             }
             unset($newShadowPathOffset[$shadowPath]);
         }
         // new parents
         if (count($newShadowPathOffset) > 0 && null !== $anyOldOffset) {
             $anyPath = $currentPaths[$anyOldOffset];
             $newParents = array_values($newShadowPathOffset);
             foreach ($newParents as $newParentOffset) {
                 $newParent = $newPaths[$newParentOffset];
                 // insert into ... select
                 // REPLACE(path, $anyPath->path, $newParent->path) as path,
                 // REPLACE(shadow_path, $anyPath->shadow_path, $newParent->shadow_path) as shadow_path
                 // from ... where shadow_path LIKE '$anyPath->shadow_path/%'
                 $this->_backend->copyTreeByShadowPath($anyPath->shadow_path, $newParent->path, $anyPath->path, $newParent->shadow_path, $anyPath->shadow_path);
             }
         }
         //execute deletes only now, important to make 100% sure "new parents" just above still has data to work on!
         foreach ($toDelete as $delete) {
             // delete where shadow_path LIKE '$delete/%'
             $this->_backend->deleteForShadowPathTree($delete);
         }
     }
     // delete current paths of this record
     $this->deletePathsForRecord($record);
     // recreate new paths of this record
     foreach ($newPaths as $path) {
         $this->_backend->create($path);
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Created ' . count($newPaths) . ' paths.');
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . print_r($newPaths->toArray(), true));
     }
     return $newPaths;
 }
コード例 #14
0
 /**
  * create a new system container
  * - by default user group gets READ grant
  * - by default admin group gets all grants
  *
  * NOTE: this should never be called in user land and only in admin/setup contexts
  * 
  * @param Tinebase_Model_Application|string $application app record, app id or app name
  * @param string $name
  * @param string $idConfig save id in config if given
  * @param Tinebase_Record_RecordSet $grants use this to overwrite default grants
  * @param string $model the model the container contains
  * @return Tinebase_Model_Container
  */
 public function createSystemContainer($application, $name, $configId = NULL, Tinebase_Record_RecordSet $grants = NULL, $model = NULL)
 {
     $application = $application instanceof Tinebase_Model_Application ? $application : Tinebase_Application::getInstance()->getApplicationById($application);
     if ($model === null) {
         $controller = Tinebase_Core::getApplicationInstance($application->name, '', true);
         $model = $controller->getDefaultModel();
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Creating system container for model ' . $model);
     }
     $newContainer = new Tinebase_Model_Container(array('name' => $name, 'type' => Tinebase_Model_Container::TYPE_SHARED, 'backend' => 'Sql', 'application_id' => $application->getId(), 'model' => $model));
     $groupsBackend = Tinebase_Group::getInstance();
     $grants = $grants ? $grants : new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array(array('account_id' => $groupsBackend->getDefaultGroup()->getId(), 'account_type' => Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP, Tinebase_Model_Grants::GRANT_READ => true, Tinebase_Model_Grants::GRANT_EXPORT => true, Tinebase_Model_Grants::GRANT_SYNC => true), array('account_id' => $groupsBackend->getDefaultAdminGroup()->getId(), 'account_type' => Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP, Tinebase_Model_Grants::GRANT_READ => true, Tinebase_Model_Grants::GRANT_ADD => true, Tinebase_Model_Grants::GRANT_EDIT => true, Tinebase_Model_Grants::GRANT_DELETE => true, Tinebase_Model_Grants::GRANT_ADMIN => true, Tinebase_Model_Grants::GRANT_EXPORT => true, Tinebase_Model_Grants::GRANT_SYNC => true)), TRUE);
     $newContainer = Tinebase_Container::getInstance()->addContainer($newContainer, $grants, TRUE);
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Created new system container ' . $name . ' for application ' . $application->name);
     }
     if ($configId !== NULL) {
         $configClass = $application->name . '_Config';
         if (@class_exists($configClass)) {
             $config = call_user_func(array($configClass, 'getInstance'));
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Setting system container config "' . $configId . '" = ' . $newContainer->getId());
             }
             $config->set($configId, $newContainer->getId());
         } else {
             if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
                 Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not find preferences class ' . $configClass);
             }
         }
     }
     $this->resetClassCache();
     return $newContainer;
 }
コード例 #15
0
 /**
  * delete linked objects (notes, relations, ...) of record
  *
  * @param Tinebase_Record_Interface $_record
  */
 protected function _deleteLinkedObjects(Tinebase_Record_Interface $_record)
 {
     // delete notes & relations
     if ($_record->has('notes')) {
         Tinebase_Notes::getInstance()->deleteNotesOfRecord($this->_modelName, $this->_backend->getType(), $_record->getId());
     }
     if ($_record->has('relations')) {
         $relations = Tinebase_Relations::getInstance()->getRelations($this->_modelName, $this->_backend->getType(), $_record->getId());
         if (!empty($relations)) {
             // remove relations
             Tinebase_Relations::getInstance()->setRelations($this->_modelName, $this->_backend->getType(), $_record->getId(), array());
             // remove related objects
             if (!empty($this->_relatedObjectsToDelete)) {
                 foreach ($relations as $relation) {
                     if (in_array($relation->related_model, $this->_relatedObjectsToDelete)) {
                         list($appName, $i, $itemName) = explode('_', $relation->related_model);
                         $appController = Tinebase_Core::getApplicationInstance($appName, $itemName);
                         $appController->delete($relation->related_id);
                     }
                 }
             }
         }
     }
 }
コード例 #16
0
 /**
  * set controller
  */
 protected function _setController()
 {
     $this->_controller = Tinebase_Core::getApplicationInstance($this->_options['model']);
 }
コード例 #17
0
 /**
  * merge duplicate shared tags
  * 
  * @param string $model record model for which tags should be merged
  * @param boolean $deleteObsoleteTags
  * @param boolean $ignoreAcl
  * 
  * @see 0007354: function for merging duplicate tags
  */
 public function mergeDuplicateSharedTags($model, $deleteObsoleteTags = TRUE, $ignoreAcl = FALSE)
 {
     $select = $this->_db->select()->from(array('tags' => SQL_TABLE_PREFIX . 'tags'), 'name')->where($this->_db->quoteIdentifier('type') . ' = ?', Tinebase_Model_Tag::TYPE_SHARED)->where($this->_db->quoteIdentifier('is_deleted') . ' = 0')->group('name')->having('COUNT(' . $this->_db->quoteIdentifier('name') . ') > 1');
     $queryResult = $this->_db->fetchAll($select);
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found ' . count($queryResult) . ' duplicate tag names.');
     }
     $controller = Tinebase_Core::getApplicationInstance($model);
     if ($ignoreAcl) {
         $containerChecks = $controller->doContainerACLChecks(FALSE);
     }
     $recordFilterModel = $model . 'Filter';
     foreach ($queryResult as $duplicateTag) {
         $filter = new Tinebase_Model_TagFilter(array('name' => $duplicateTag['name'], 'type' => Tinebase_Model_Tag::TYPE_SHARED));
         $paging = new Tinebase_Model_Pagination(array('sort' => 'creation_time'));
         $tagsWithSameName = $this->searchTags($filter, $paging);
         $targetTag = $tagsWithSameName->getFirstRecord();
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Merging tag ' . $duplicateTag['name'] . '. Found ' . count($tagsWithSameName) . ' tags with this name.');
         }
         foreach ($tagsWithSameName as $tag) {
             if ($tag->getId() === $targetTag->getId()) {
                 // skip target (oldest) tag
                 continue;
             }
             $recordFilter = new $recordFilterModel(array(array('field' => 'tag', 'operator' => 'in', 'value' => array($tag->getId()))));
             $recordIdsWithTagToMerge = $controller->search($recordFilter, NULL, FALSE, TRUE);
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found ' . count($recordIdsWithTagToMerge) . ' ' . $model . '(s) with tags to be merged.');
             }
             if (!empty($recordIdsWithTagToMerge)) {
                 $recordFilter = new $recordFilterModel(array(array('field' => 'id', 'operator' => 'in', 'value' => $recordIdsWithTagToMerge)));
                 $this->attachTagToMultipleRecords($recordFilter, $targetTag);
                 $this->detachTagsFromMultipleRecords($recordFilter, $tag->getId());
             }
             // check occurrence of the merged tag and remove it if obsolete
             $tag = $this->get($tag);
             if ($deleteObsoleteTags && $tag->occurrence == 0) {
                 $this->deleteTags($tag->getId(), $ignoreAcl);
             }
         }
     }
     if ($ignoreAcl) {
         /** @noinspection PhpUndefinedVariableInspection */
         $controller->doContainerACLChecks($containerChecks);
     }
 }
コード例 #18
0
 /**
  * returns the personal container of a given account accessible by a another given account
  *
  * @param   string|Tinebase_Model_User          $_accountId
  * @param   string                              $_application
  * @param   int|Tinebase_Model_User             $_owner
  * @param   array|string                        $_grant
  * @param   bool                                $_ignoreACL
  * @return  Tinebase_Record_RecordSet of subtype Tinebase_Model_Container
  * @throws  Tinebase_Exception_NotFound
  */
 public function getPersonalContainer($_accountId, $_application, $_owner, $_grant, $_ignoreACL = false)
 {
     $accountId = Tinebase_Model_User::convertUserIdToInt($_accountId);
     $ownerId = Tinebase_Model_User::convertUserIdToInt($_owner);
     $grant = $_ignoreACL ? '*' : $_grant;
     $application = Tinebase_Application::getInstance()->getApplicationByName($_application);
     $select = $this->_db->select()->from(array('owner' => SQL_TABLE_PREFIX . 'container_acl'), array())->join(array('user' => SQL_TABLE_PREFIX . 'container_acl'), "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('user.container_id')}", array())->join(array('container' => SQL_TABLE_PREFIX . 'container'), "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('container.id')}")->where("{$this->_db->quoteIdentifier('owner.account_id')} = ?", $ownerId)->where("{$this->_db->quoteIdentifier('owner.account_grant')} = ?", Tinebase_Model_Grants::GRANT_ADMIN)->where("{$this->_db->quoteIdentifier('container.application_id')} = ?", $application->getId())->where("{$this->_db->quoteIdentifier('container.type')} = ?", Tinebase_Model_Container::TYPE_PERSONAL)->where("{$this->_db->quoteIdentifier('container.is_deleted')} = ?", 0, Zend_Db::INT_TYPE)->group('container.id')->order('container.name');
     $this->addGrantsSql($select, $accountId, $grant, 'user');
     $select = Tinebase_Backend_Sql_Abstract::traitGroup($this->_db, $this->_tablePrefix, $select);
     $stmt = $this->_db->query($select);
     $containersData = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
     // if no containers where found,  maybe something went wrong when creating the initial folder
     // let's check if the controller of the application has a function to create the needed folders
     if (empty($containersData) and $accountId === $ownerId) {
         $application = Tinebase_Core::getApplicationInstance($application->name);
         if ($application instanceof Tinebase_Container_Interface) {
             return $application->createPersonalFolder($accountId);
         }
     }
     $containers = new Tinebase_Record_RecordSet('Tinebase_Model_Container', $containersData, TRUE);
     return $containers;
 }
コード例 #19
0
 /**
  * magic method for json api
  *
  * @param string $method
  * @param array  $args
  */
 public function __call($method, array $args)
 {
     // provides api for default application methods
     if (preg_match('/^(get|save|search|delete)([a-z0-9]+)/i', $method, $matches)) {
         $apiMethod = $matches[1];
         $model = in_array($apiMethod, array('search', 'delete')) ? substr($matches[2], 0, -1) : $matches[2];
         $modelController = Tinebase_Core::getApplicationInstance($this->_applicationName, $model);
         switch ($apiMethod) {
             case 'get':
                 return $this->_get($args[0], $modelController);
                 break;
             case 'save':
                 return $this->_save($args[0], $modelController, $model);
                 break;
             case 'search':
                 $filterName = $this->_applicationName . '_Model_' . $model . 'Filter';
                 return $this->_search($args[0], $args[1], $modelController, $filterName, true);
                 break;
             case 'delete':
                 return $this->_delete($args[0], $modelController);
                 break;
         }
     }
     // call plugin method (see Tinebase_Pluggable_Abstract)
     return parent::__call($method, $args);
 }
コード例 #20
0
 /**
  * execute action defined in queue message
  * 
  * @param  array  $message  action
  * @return mixed
  */
 public function executeAction($message)
 {
     if (!is_array($message) || !(isset($message['action']) || array_key_exists('action', $message)) || strpos($message['action'], '.') === FALSE) {
         throw new Tinebase_Exception_NotFound('Could not execute action, invalid message/action param');
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " executing action: '{$message['action']}'");
     }
     list($appName, $actionName) = explode('.', $message['action']);
     $controller = Tinebase_Core::getApplicationInstance($appName);
     if (!method_exists($controller, $actionName)) {
         throw new Tinebase_Exception_NotFound('Could not execute action, requested action does not exist');
     }
     return call_user_func_array(array($controller, $actionName), $message['params']);
 }
 /**
  * returns array with the filter settings of this filter
  *
  * @param  bool $valueToJson resolve value for json api?
  * @return array
  */
 public function toArray($valueToJson = false)
 {
     $result = parent::toArray($valueToJson);
     if (strtolower($this->_cfRecord->definition['type']) == 'record') {
         try {
             $modelParts = explode('.', $this->_cfRecord->definition['recordConfig']['value']['records']);
             // get model parts from saved record class e.g. Tine.Admin.Model.Group
             $controller = Tinebase_Core::getApplicationInstance($modelParts[1], $modelParts[3]);
             $result['value']['value'] = $controller->get($result['value']['value'])->toArray();
         } catch (Exception $e) {
             if (Tinebase_Core::isLogLevel(Zend_Log::ERR)) {
                 Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Error resolving custom field record: ' . $e->getMessage());
             }
             $result['value']['value'] = $customField->value;
         }
     }
     return $result;
 }
コード例 #22
0
 /**
  * get controller
  * 
  * @return Tinebase_Controller_Record_Abstract|null
  */
 protected function _getController()
 {
     if ($this->_controller === null) {
         if (isset($this->_options['controller'])) {
             $cname = $this->_options['controller'];
             $this->_controller = $cname::getInstance();
         } elseif (isset($this->_options['modelName'])) {
             $this->_controller = Tinebase_Core::getApplicationInstance($this->_options['modelName']);
         } else {
             Tinebase_Core::getLogger()->INFO(__METHOD__ . '::' . __LINE__ . ' No modelName or controller defined in filter options, can not resolve record.');
             return null;
         }
     }
     return $this->_controller;
 }
コード例 #23
0
 /**
  * download file attachment
  * 
  * @param string $nodeId
  * @param string $recordId
  * @param string $modelName
  */
 public function downloadRecordAttachment($nodeId, $recordId, $modelName)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Downloading attachment of ' . $modelName . ' record with id ' . $recordId);
     }
     $recordController = Tinebase_Core::getApplicationInstance($modelName);
     $record = $recordController->get($recordId);
     $node = Tinebase_FileSystem::getInstance()->get($nodeId);
     $path = Tinebase_Model_Tree_Node_Path::STREAMWRAPPERPREFIX . Tinebase_FileSystem_RecordAttachments::getInstance()->getRecordAttachmentPath($record) . '/' . $node->name;
     $this->_downloadFileNode($node, $path);
     exit;
 }
コード例 #24
0
 /**
  * 
  * @return Tinebase_Controller_Record_Interface
  */
 protected function _getController()
 {
     if ($this->_controller === null) {
         $this->_controller = Tinebase_Core::getApplicationInstance($this->_application->name, $this->_model);
     }
     return $this->_controller;
 }
コード例 #25
0
 /**
  * clean relations, set relation to deleted if at least one of the ends has been set to deleted or pruned
  */
 public function cleanRelations()
 {
     $relations = Tinebase_Relations::getInstance();
     $filter = new Tinebase_Model_Filter_FilterGroup();
     $pagination = new Tinebase_Model_Pagination();
     $pagination->limit = 10000;
     $pagination->sort = 'id';
     $totalCount = 0;
     $date = Tinebase_DateTime::now()->subYear(1);
     while (($recordSet = $relations->search($filter, $pagination)) && $recordSet->count() > 0) {
         $filter = new Tinebase_Model_Filter_FilterGroup();
         $pagination->start += $pagination->limit;
         $models = array();
         foreach ($recordSet as $relation) {
             $models[$relation->own_model][$relation->own_id][] = $relation->id;
             $models[$relation->related_model][$relation->related_id][] = $relation->id;
         }
         foreach ($models as $model => &$ids) {
             $doAll = false;
             try {
                 $app = Tinebase_Core::getApplicationInstance($model, '', true);
             } catch (Tinebase_Exception_NotFound $tenf) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                     Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' model: ' . $model . ' no application found for it');
                 }
                 $doAll = true;
             }
             if (!$doAll) {
                 if ($app instanceof Tinebase_Container) {
                     $backend = $app;
                 } else {
                     if (!$app instanceof Tinebase_Controller_Record_Abstract) {
                         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' model: ' . $model . ' controller: ' . get_class($app) . ' not an instance of Tinebase_Controller_Record_Abstract');
                         }
                         continue;
                     }
                     $backend = $app->getBackend();
                 }
                 if (!$backend instanceof Tinebase_Backend_Interface) {
                     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' model: ' . $model . ' backend: ' . get_class($backend) . ' not an instance of Tinebase_Backend_Interface');
                     }
                     continue;
                 }
                 $record = new $model(null, true);
                 $modelFilter = $model . 'Filter';
                 $idFilter = new $modelFilter(array(), '', array('ignoreAcl' => true));
                 $idFilter->addFilter(new Tinebase_Model_Filter_Id(array('field' => $record->getIdProperty(), 'operator' => 'in', 'value' => array_keys($ids))));
                 $existingIds = $backend->search($idFilter, null, true);
                 if (!is_array($existingIds)) {
                     throw new Exception('search for model: ' . $model . ' returned not an array!');
                 }
                 foreach ($existingIds as $id) {
                     unset($ids[$id]);
                 }
             }
             if (count($ids) > 0) {
                 $toDelete = array();
                 foreach ($ids as $idArrays) {
                     foreach ($idArrays as $id) {
                         $toDelete[$id] = true;
                     }
                 }
                 $toDelete = array_keys($toDelete);
                 foreach ($toDelete as $id) {
                     if ($recordSet->getById($id)->creation_time && $recordSet->getById($id)->creation_time->isLater($date)) {
                         Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' relation is about to get deleted that is younger than 1 year: ' . print_r($recordSet->getById($id)->toArray(false), true));
                     }
                 }
                 $relations->delete($toDelete);
                 $totalCount += count($toDelete);
             }
         }
     }
     $message = 'Deleted ' . $totalCount . ' relations in total';
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' . $message);
     }
     echo $message . "\n";
 }
コード例 #26
0
 /**
  * delete linked relations
  * 
  * @param Tinebase_Record_Interface $_record
  * 
  * TODO check if this needs to be done, as we might already deleting this "from the other side"
  */
 protected function _deleteLinkedRelations(Tinebase_Record_Interface $_record)
 {
     $relations = Tinebase_Relations::getInstance()->getRelations($this->_modelName, $this->_getBackendType(), $_record->getId());
     if (empty($relations)) {
         return;
     }
     // remove relations
     Tinebase_Relations::getInstance()->setRelations($this->_modelName, $this->_getBackendType(), $_record->getId(), array());
     if (empty($this->_relatedObjectsToDelete)) {
         return;
     }
     // remove related objects
     Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Deleting all ' . implode(',', $this->_relatedObjectsToDelete) . ' relations.');
     foreach ($relations as $relation) {
         if (in_array($relation->related_model, $this->_relatedObjectsToDelete)) {
             list($appName, $i, $itemName) = explode('_', $relation->related_model);
             $appController = Tinebase_Core::getApplicationInstance($appName, $itemName);
             try {
                 $appController->delete($relation->related_id);
             } catch (Exception $e) {
                 Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Error deleting: ' . $e->getMessage());
             }
         }
     }
 }
コード例 #27
0
 /**
  * return autocomplete suggestions for a given recordclass, the property and value
  *
  * @param string $appName
  * @param string $modelName
  * @param string $property
  * @param string $startswith
  * 
  * @return array
  */
 public function autoComplete($appName, $modelName, $property, $startswith)
 {
     $recordClassName = $appName . '_Model_' . $modelName;
     $controller = Tinebase_Core::getApplicationInstance($appName, $modelName);
     $filterClassName = $recordClassName . 'Filter';
     if (!class_exists($recordClassName)) {
         throw new Tinebase_Exception_InvalidArgument('A record class for the given appName and modelName does not exist!');
     }
     if (!$controller) {
         throw new Tinebase_Exception_InvalidArgument('A controller for the given appName and modelName does not exist!');
     }
     if (!class_exists($filterClassName)) {
         throw new Tinebase_Exception_InvalidArgument('A filter for the given appName and modelName does not exist!');
     }
     if (!in_array($property, $recordClassName::getAutocompleteFields())) {
         throw new Tinebase_Exception_UnexpectedValue('bad property name');
     }
     $filter = new $filterClassName(array(array('field' => $property, 'operator' => 'startswith', 'value' => $startswith)));
     $paging = new Tinebase_Model_Pagination(array('sort' => $property));
     $values = array_unique($controller->search($filter, $paging)->{$property});
     $result = array('results' => array(), 'totalcount' => count($values));
     foreach ($values as $value) {
         $result['results'][] = array($property => $value);
     }
     return $result;
 }
 /**
  * gets image info and data
  * 
  * @param   string $application application which manages the image
  * @param   string $identifier identifier of image/record
  * @param   string $location optional additional identifier
  * @return  Tinebase_Model_Image
  * @throws  Tinebase_Exception_NotFound
  * @throws  Tinebase_Exception_UnexpectedValue
  */
 public function getImage($application, $identifier, $location = '')
 {
     if ($location === 'vfs') {
         $node = Tinebase_FileSystem::getInstance()->get($identifier);
         $path = Tinebase_Model_Tree_Node_Path::STREAMWRAPPERPREFIX . Tinebase_FileSystem::getInstance()->getPathOfNode($node, true);
         $image = Tinebase_ImageHelper::getImageInfoFromBlob(file_get_contents($path));
     } else {
         if ($application == 'Tinebase' && $location == 'tempFile') {
             $tempFile = Tinebase_TempFile::getInstance()->getTempFile($identifier);
             $image = Tinebase_ImageHelper::getImageInfoFromBlob(file_get_contents($tempFile->path));
         } else {
             $appController = Tinebase_Core::getApplicationInstance($application);
             if (!method_exists($appController, 'getImage')) {
                 throw new Tinebase_Exception_NotFound("{$application} has no getImage function.");
             }
             $image = $appController->getImage($identifier, $location);
         }
     }
     if (!$image instanceof Tinebase_Model_Image) {
         if (is_array($image)) {
             $image = new Tinebase_Model_Image($image + array('application' => $application, 'id' => $identifier, 'location' => $location));
         } else {
             throw new Tinebase_Exception_UnexpectedValue('broken image');
         }
     }
     return $image;
 }
コード例 #29
0
 /**
  * Used for updating multiple records
  * 
  * @param string $appName
  * @param string $modelName
  * @param array $changes
  * @param array $filter
  */
 public function updateMultipleRecords($appName, $modelName, $changes, $filter)
 {
     $filterModel = $appName . '_Model_' . $modelName . 'Filter';
     foreach ($changes as $f) {
         $data[preg_replace('/^customfield_/', '#', $f['name'])] = $f['value'];
     }
     return $this->_updateMultiple($filter, $data, Tinebase_Core::getApplicationInstance($appName, $modelName), $filterModel);
 }
コード例 #30
0
 /**
  * append relation filter
  *
  * @param string $ownModel
  * @param array $relationsToSearchIn
  * @return Tinebase_Model_Filter_Id
  */
 protected function _getAdvancedSearchFilter($ownModel = null, $relationsToSearchIn = null)
 {
     if (Tinebase_Core::get('ADVANCED_SEARCHING') || !Tinebase_Core::getPreference()->getValue(Tinebase_Preference::ADVANCED_SEARCH, false) || empty($relationsToSearchIn)) {
         return null;
     }
     if (0 === strpos($this->_operator, 'not')) {
         $not = true;
         $operator = substr($this->_operator, 3);
     } else {
         $not = false;
         $operator = $this->_operator;
     }
     $ownIds = array();
     foreach ((array) $relationsToSearchIn as $relatedModel) {
         $filterModel = $relatedModel . 'Filter';
         // prevent recursion here
         // TODO find a better way for this, maybe we could pass this an option to all filters in filter model
         Tinebase_Core::set('ADVANCED_SEARCHING', true);
         $relatedFilter = new $filterModel(array(array('field' => 'query', 'operator' => $operator, 'value' => $this->_value)));
         $relatedIds = Tinebase_Core::getApplicationInstance($relatedModel)->search($relatedFilter, NULL, FALSE, TRUE);
         Tinebase_Core::set('ADVANCED_SEARCHING', false);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found ' . count($relatedIds) . ' related ids');
         }
         $relationFilter = new Tinebase_Model_RelationFilter(array(array('field' => 'own_model', 'operator' => 'equals', 'value' => $ownModel), array('field' => 'related_model', 'operator' => 'equals', 'value' => $relatedModel), array('field' => 'related_id', 'operator' => 'in', 'value' => $relatedIds)));
         $ownIds = array_merge($ownIds, Tinebase_Relations::getInstance()->search($relationFilter, NULL)->own_id);
     }
     return new Tinebase_Model_Filter_Id('id', $not ? 'notin' : 'in', $ownIds);
 }