Пример #1
0
 protected function actionGroupsWithResources($params)
 {
     $stmt = \GO\Calendar\Model\Group::model()->find(\GO\Base\Db\FindParams::newInstance()->order('t.name')->criteria(\GO\Base\Db\FindCriteria::newInstance()->addCondition('id', 1, '>')));
     $response['results'] = array();
     $response['total'] = 0;
     while ($group = $stmt->fetch()) {
         $record = $group->getAttributes('formatted');
         if (\GO::modules()->customfields) {
             $record['customfields'] = \GO\Customfields\Controller\CategoryController::getEnabledCategoryData("GO\\Calendar\\Model\\Event", $group->id);
         } else {
             $record['customfields'] = array();
         }
         $record['resources'] = array();
         $calStmt = \GO\Calendar\Model\Calendar::model()->find(\GO\Base\Db\FindParams::newInstance()->permissionLevel(\GO\Base\Model\Acl::READ_PERMISSION)->joinCustomFields()->order('t.name')->criteria(\GO\Base\Db\FindCriteria::newInstance()->addCondition('group_id', $group->id)));
         while ($resource = $calStmt->fetch()) {
             $resourceRecord = $resource->getAttributes('formatted');
             $record['resources'][] = $resourceRecord;
         }
         $num_resources = count($record['resources']);
         if ($num_resources > 0) {
             $response['results'][] = $record;
             $response['total'] += $num_resources;
         }
     }
     return $response;
 }
Пример #2
0
 private function calendars()
 {
     $calendars = Calendar::model()->findByAttributes(array('user_id' => $this->from));
     $success = true;
     foreach ($calendars as $calendar) {
         $calendar->user_id = $this->to;
         $success = $calendar->save() && $success;
     }
     return $success;
 }
Пример #3
0
 private function _updateAllDefaultCalendars(&$feedback = '')
 {
     $stmt = \GO\Calendar\Model\Calendar::model()->find(\GO\Base\Db\FindParams::newInstance()->ignoreAcl()->joinModel(array('model' => 'GO\\Calendar\\Model\\Settings', 'localTableAlias' => 't', 'localField' => 'id', 'foreignField' => 'calendar_id', 'tableAlias' => 'sett')));
     while ($updateModel = $stmt->fetch()) {
         try {
             $updateModel->setDefaultAttributes(false);
             $updateModel->save();
         } catch (\Exception $e) {
             $feedback .= $e->getMessage();
         }
     }
 }
Пример #4
0
 protected function actionCalendarStore()
 {
     $colModel = new \GO\Base\Data\ColumnModel(\GO\Favorites\Model\Calendar::model());
     $colModel->setColumnsFromModel(\GO\Calendar\Model\Calendar::model());
     $findParams = new \GO\Base\Db\FindParams();
     $findParams->getCriteria()->addCondition('user_id', \GO::user()->id, '=', 'cal');
     $findParams->order('name');
     $findParams->joinModel(array('model' => 'GO\\Favorites\\Model\\Calendar', 'localTableAlias' => 't', 'localField' => 'id', 'foreignField' => 'calendar_id', 'tableAlias' => 'cal', 'type' => 'INNER'));
     $store = new \GO\Base\Data\DbStore('GO\\Calendar\\Model\\Calendar', $colModel, $_POST, $findParams);
     $store->defaultSort = array('name');
     $store->multiSelectable('calendars');
     echo $this->renderStore($store);
 }
Пример #5
0
 /**
  * The code that needs to be called when the cron is running
  * 
  * If $this->enableUserAndGroupSupport() returns TRUE then the run function 
  * will be called for each $user. (The $user parameter will be given)
  * 
  * If $this->enableUserAndGroupSupport() returns FALSE then the 
  * $user parameter is null and the run function will be called only once.
  * 
  * @param \GO\Base\Cron\CronJob $cronJob
  * @param \GO\Base\Model\User $user [OPTIONAL]
  */
 public function run(\GO\Base\Cron\CronJob $cronJob, \GO\Base\Model\User $user = null)
 {
     \GO::session()->runAsRoot();
     \GO::debug("Start updating public calendars.");
     $calendars = \GO\Calendar\Model\Calendar::model()->findByAttribute('public', true);
     foreach ($calendars as $calendar) {
         $file = new \GO\Base\Fs\File($calendar->getPublicIcsPath());
         if (!$file->exists()) {
             \GO::debug("Creating " . $file->path() . ".");
             $file->touch(true);
         }
         $file->putContents($calendar->toVObject());
         \GO::debug("Updating " . $calendar->name . " to " . $file->path() . ".");
     }
     \GO::debug("Finished updating public calendars.");
 }
Пример #6
0
 /**
  * Get the data for the grid that shows all the tasks from the selected calendars.
  * 
  * @param Array $params
  * @return Array The array with the data for the grid. 
  */
 protected function actionPortletGrid($params)
 {
     $local_time = time();
     $year = date("Y", $local_time);
     $month = date("m", $local_time);
     $day = date("j", $local_time);
     $periodStartTime = mktime(0, 0, 0, $month, $day, $year);
     $periodEndTime = mktime(0, 0, 0, $month, $day + 2, $year);
     $today_end = mktime(0, 0, 0, $month, $day + 1, $year);
     $joinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addCondition('user_id', \GO::user()->id, '=', 'pt')->addCondition('calendar_id', 'pt.calendar_id', '=', 't', true, true);
     $calendarJoinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addCondition('calendar_id', 'tl.id', '=', 't', true, true);
     $findParams = \GO\Base\Db\FindParams::newInstance()->select('t.*, tl.name AS calendar_name')->join(\GO\Calendar\Model\PortletCalendar::model()->tableName(), $joinCriteria, 'pt')->join(\GO\Calendar\Model\Calendar::model()->tableName(), $calendarJoinCriteria, 'tl');
     $events = \GO\Calendar\Model\Event::model()->findCalculatedForPeriod($findParams, $periodStartTime, $periodEndTime);
     $store = new \GO\Base\Data\ArrayStore();
     foreach ($events as $event) {
         $record = $event->getResponseData();
         $record['day'] = $event->getAlternateStartTime() < $today_end ? \GO::t('today') : \GO::t('tomorrow');
         $record['time'] = $event->getEvent()->all_day_event == 1 ? '-' : $record['time'];
         $store->addRecord($record);
     }
     return $store->getData();
 }
Пример #7
0
 protected function actionRemoveEmptyStuff($params)
 {
     if (!$this->isCli() && !GO::modules()->tools) {
         throw new \GO\Base\Exception\AccessDenied();
     }
     GO::session()->closeWriting();
     GO::setIgnoreAclPermissions(true);
     if (!$this->isCli()) {
         echo '<pre>';
     }
     if (\GO::modules()->isInstalled("addressbook")) {
         echo "\n\nProcessing addressbook\n";
         flush();
         $stmt = \GO\Addressbook\Model\Addressbook::model()->find();
         while ($addressbook = $stmt->fetch()) {
             $contactStmt = $addressbook->contacts();
             $companiesStmt = $addressbook->companies();
             if (!$contactStmt->rowCount() && !$companiesStmt->rowCount()) {
                 echo "Removing " . $addressbook->name . "\n";
                 $addressbook->delete();
                 flush();
             }
         }
     }
     if (\GO::modules()->isInstalled("calendar")) {
         echo "\n\nProcessing calendar\n";
         flush();
         $stmt = \GO\Calendar\Model\Calendar::model()->find();
         while ($calendar = $stmt->fetch()) {
             $eventStmt = $calendar->events();
             if (!$eventStmt->rowCount()) {
                 echo "Removing " . $calendar->name . "\n";
                 $calendar->delete();
                 flush();
             }
         }
     }
     if (\GO::modules()->isInstalled("tasks")) {
         echo "\n\nProcessing tasks\n";
         flush();
         $stmt = \GO\Tasks\Model\Tasklist::model()->find();
         while ($tasklist = $stmt->fetch()) {
             $eventStmt = $tasklist->tasks();
             if (!$eventStmt->rowCount()) {
                 echo "Removing " . $tasklist->name . "\n";
                 $tasklist->delete();
                 flush();
             }
         }
     }
     if (\GO::modules()->isInstalled("notes")) {
         echo "\n\nProcessing notes\n";
         flush();
         $stmt = \GO\Notes\Model\Category::model()->find();
         while ($cat = $stmt->fetch()) {
             $eventStmt = $cat->notes();
             if (!$eventStmt->rowCount()) {
                 echo "Removing " . $cat->name . "\n";
                 $cat->delete();
                 flush();
             }
         }
     }
 }
Пример #8
0
    protected function actionCreate($params)
    {
        if ($this->isCli()) {
            \GO::session()->runAsRoot();
        } elseif (!\GO::user()->isAdmin()) {
            throw new \GO\Base\Exception\AccessDenied();
        }
        if (\GO::modules()->customfields) {
            $customfieldModels = \GO\Customfields\CustomfieldsModule::getCustomfieldModels();
            $types = \GO\Customfields\CustomfieldsModule::getCustomfieldTypes();
            foreach ($customfieldModels as $model) {
                //				echo $model->getName(),'<br />';
                $category = \GO\Customfields\Model\Category::model()->createIfNotExists(\GO::getModel($model->getName())->extendsModel(), "Demo Custom fields");
                $category->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::WRITE_PERMISSION);
                if (strpos(\GO::getModel($model->getName())->extendsModel(), 'Addressbook\\')) {
                    foreach ($types as $t) {
                        \GO\Customfields\Model\Field::model()->createIfNotExists($category->id, $t['type'], array('datatype' => $t['className'], 'helptext' => $t['className'] == "GO\\Customfields\\Customfieldtype\\Text" ? "Some help text for this field" : ""));
                    }
                } else {
                    \GO\Customfields\Model\Field::model()->createIfNotExists($category->id, "Custom", array('datatype' => "GO\\Customfields\\Customfieldtype\\Text", 'helptext' => "Some help text for this field"));
                }
            }
        }
        $addressbook = \GO\Addressbook\Model\Addressbook::model()->findSingleByAttribute('name', \GO::t('customers', 'addressbook'));
        if (!$addressbook) {
            $addressbook = new \GO\Addressbook\Model\Addressbook();
            $addressbook->setAttributes(array('user_id' => 1, 'name' => \GO::t('prospects', 'addressbook'), 'default_salutation' => \GO::t('defaultSalutation', 'addressbook')));
            $addressbook->save();
            $addressbook->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::WRITE_PERMISSION);
        }
        $company = \GO\Addressbook\Model\Company::model()->findSingleByAttribute('email', '*****@*****.**');
        if (!$company) {
            $company = new \GO\Addressbook\Model\Company();
            $company->setAttributes(array('addressbook_id' => $addressbook->id, 'name' => 'Smith Inc', 'address' => 'Kalverstraat', 'address_no' => '1', 'zip' => '1012 NX', 'city' => 'Amsterdam', 'state' => 'Noord-Holland', 'country' => 'NL', 'post_address' => 'Kalverstraat', 'post_address_no' => '1', 'post_zip' => '1012 NX', 'post_city' => 'Amsterdam', 'post_state' => 'Noord-Brabant', 'post_country' => 'NL', 'phone' => '+31 (0) 10 - 1234567', 'fax' => '+31 (0) 1234567', 'email' => '*****@*****.**', 'homepage' => 'http://www.smith.demo', 'bank_no' => '', 'vat_no' => 'NL 1234.56.789.B01', 'user_id' => 1, 'comment' => 'Just a demo company'));
            $company->save();
        }
        $john = \GO\Addressbook\Model\Contact::model()->findSingleByAttribute('email', '*****@*****.**');
        if (!$john) {
            $john = new \GO\Addressbook\Model\Contact();
            $john->addressbook_id = $addressbook->id;
            $john->company_id = $company->id;
            $john->salutation = 'Dear Mr. Smith';
            $john->first_name = 'John';
            $john->last_name = 'Smith';
            $john->function = 'CEO';
            $john->cellular = '06-12345678';
            $john->email = '*****@*****.**';
            $john->address = 'Kalverstraat';
            $john->address_no = '1';
            $john->zip = '1012 NX';
            $john->city = 'Amsterdam';
            $john->state = 'Noord-Holland';
            $john->country = 'NL';
            $john->url_facebook = 'http://www.facebook.com';
            $john->url_linkedin = 'http://www.linkedin.com';
            $john->url_twitter = 'http://www.twitter.com';
            $john->skype_name = 'echo123';
            $john->save();
            $john->setPhoto(new \GO\Base\Fs\File(\GO::modules()->addressbook->path . 'install/noperson.jpg'));
            $john->save();
        }
        $acme = \GO\Addressbook\Model\Company::model()->findSingleByAttribute('email', '*****@*****.**');
        if (!$acme) {
            $acme = new \GO\Addressbook\Model\Company();
            $acme->setAttributes(array('addressbook_id' => $addressbook->id, 'name' => 'ACME Corporation', 'address' => '1111 Broadway', 'address_no' => '', 'zip' => '10019', 'city' => 'New York', 'state' => 'NY', 'country' => 'US', 'post_address' => '1111 Broadway', 'post_address_no' => '', 'post_zip' => '10019', 'post_city' => 'New York', 'post_state' => 'NY', 'post_country' => 'US', 'phone' => '(555) 123-4567', 'fax' => '(555) 123-4567', 'email' => '*****@*****.**', 'homepage' => 'http://www.acme.demo', 'bank_no' => '', 'vat_no' => 'US 1234.56.789.B01', 'user_id' => 1, 'comment' => 'The name Acme became popular for businesses by the 1920s, when alphabetized business telephone directories such as the Yellow Pages began to be widespread. There were a flood of businesses named Acme (some of these still survive[1]). For example, early Sears catalogues contained a number of products with the "Acme" trademark, including anvils, which are frequently used in Warner Bros. cartoons.[2]'));
            $acme->save();
            $acme->addComment("The company is never clearly defined in Road Runner cartoons but appears to be a conglomerate which produces every product type imaginable, no matter how elaborate or extravagant - none of which ever work as desired or expected. In the Road Runner cartoon Beep, Beep, it was referred to as \"Acme Rocket-Powered Products, Inc.\" based in Fairfield, New Jersey. Many of its products appear to be produced specifically for Wile E. Coyote; for example, the Acme Giant Rubber Band, subtitled \"(For Tripping Road Runners)\".");
            $acme->addComment("Sometimes, Acme can also send living creatures through the mail, though that isn't done very often. Two examples of this are the Acme Wild-Cat, which had been used on Elmer Fudd and Sam Sheepdog (which doesn't maul its intended victim); and Acme Bumblebees in one-fifth bottles (which sting Wile E. Coyote). The Wild Cat was used in the shorts Don't Give Up the Sheep and A Mutt in a Rut, while the bees were used in the short Zoom and Bored.");
        }
        $wile = \GO\Addressbook\Model\Contact::model()->findSingleByAttribute('email', '*****@*****.**');
        if (!$wile) {
            $wile = new \GO\Addressbook\Model\Contact();
            $wile->addressbook_id = $addressbook->id;
            $wile->company_id = $acme->id;
            $wile->salutation = 'Dear Mr. Coyote';
            $wile->first_name = 'Wile';
            $wile->middle_name = 'E.';
            $wile->last_name = 'Coyote';
            $wile->function = 'CEO';
            $wile->cellular = '06-12345678';
            $wile->email = '*****@*****.**';
            $wile->address = '1111 Broadway';
            $wile->address_no = '';
            $wile->zip = '10019';
            $wile->city = 'New York';
            $wile->state = 'NY';
            $wile->country = 'US';
            $wile->url_facebook = 'http://www.facebook.com';
            $wile->url_linkedin = 'http://www.linkedin.com';
            $wile->url_twitter = 'http://www.twitter.com';
            $wile->skype_name = 'test';
            $wile->save();
            $wile->setPhoto(new \GO\Base\Fs\File(\GO::modules()->addressbook->path . 'install/wecoyote.png'));
            $wile->save();
            $wile->addComment("Wile E. Coyote (also known simply as \"The Coyote\") and The Road Runner are a duo of cartoon characters from a series of Looney Tunes and Merrie Melodies cartoons. The characters (a coyote and Greater Roadrunner) were created by animation director Chuck Jones in 1948 for Warner Bros., while the template for their adventures was the work of writer Michael Maltese. The characters star in a long-running series of theatrical cartoon shorts (the first 16 of which were written by Maltese) and occasional made-for-television cartoons.");
            $wile->addComment("In each episode, instead of animal senses and cunning, Wile E. Coyote uses absurdly complex contraptions (sometimes in the manner of Rube Goldberg) and elaborate plans to pursue his quarry. It was originally meant to parody chase cartoons like Tom and Jerry, but became popular in its own right, much to Jones' chagrin.");
            $file = new \GO\Base\Fs\File(\GO::modules()->addressbook->path . 'install/Demo letter.docx');
            $copy = $file->copy($wile->filesFolder->fsFolder);
            $wile->filesFolder->addFile($copy->name());
        }
        $internalUserGroup = \GO\Base\Model\Group::model()->findByPk(\GO::config()->group_internal);
        \GO::config()->password_validate = false;
        $elmer = \GO\Base\Model\User::model()->findSingleByAttribute('username', 'elmer');
        if (!$elmer) {
            $elmer = new \GO\Base\Model\User();
            $elmer->username = '******';
            $elmer->first_name = 'Elmer';
            $elmer->last_name = 'Fudd';
            $elmer->email = '*****@*****.**';
            $elmer->password = '******';
            if ($elmer->save()) {
                //make sure he's member of the internal group.
                $internalUserGroup->addUser($elmer->id);
                $this->_setUserContact($elmer);
                $elmer->checkDefaultModels();
            } else {
                var_dump($elmer->getValidationErrors());
                exit;
            }
        }
        $demo = \GO\Base\Model\User::model()->findSingleByAttribute('username', 'demo');
        if (!$demo) {
            $demo = new \GO\Base\Model\User();
            $demo->username = '******';
            $demo->first_name = 'Demo';
            $demo->last_name = 'User';
            $demo->email = '*****@*****.**';
            $demo->password = '******';
            if ($demo->save()) {
                //make sure he's member of the internal group.
                $internalUserGroup->addUser($demo->id);
                $this->_setUserContact($demo);
                $demo->checkDefaultModels();
            } else {
                var_dump($demo->getValidationErrors());
                exit;
            }
        }
        $linda = \GO\Base\Model\User::model()->findSingleByAttribute('username', 'linda');
        if (!$linda) {
            $linda = new \GO\Base\Model\User();
            $linda->username = '******';
            $linda->first_name = 'Linda';
            $linda->last_name = 'Smith';
            $linda->email = '*****@*****.**';
            $linda->password = '******';
            if ($linda->save()) {
                //make sure she's member of the internal group.
                $internalUserGroup->addUser($linda->id);
                $this->_setUserContact($linda);
                $linda->checkDefaultModels();
            } else {
                var_dump($linda->getValidationErrors());
                exit;
            }
        }
        if (\GO::modules()->calendar) {
            //share calendars
            \GO\Calendar\Model\Calendar::model()->getDefault($demo)->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::READ_PERMISSION);
            \GO\Calendar\Model\Calendar::model()->getDefault($elmer)->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::READ_PERMISSION);
            \GO\Calendar\Model\Calendar::model()->getDefault($linda)->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::READ_PERMISSION);
            $events = array(array('Project meeting', 10), array('Meet Wile', 12), array('MT Meeting', 14));
            //start on tuesday.
            $time = \GO\Base\Util\Date::date_add(\GO\Base\Util\Date::get_last_sunday(time()), 2);
            foreach ($events as $e) {
                $event = new \GO\Calendar\Model\Event();
                $event->name = $e[0];
                $event->location = "ACME NY Office";
                $event->start_time = \GO\Base\Util\Date::clear_time($time, $e[1]);
                $event->end_time = $event->start_time + 3600;
                $event->user_id = $demo->id;
                $event->calendar_id = \GO\Calendar\Model\Calendar::model()->getDefault($demo)->id;
                $event->save();
                $participant = new \GO\Calendar\Model\Participant();
                $participant->is_organizer = true;
                $participant->setContact($demo->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($linda->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($elmer->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($wile);
                $event->addParticipant($participant);
                $wile->link($event);
            }
            $events = array(array('Project meeting', 11), array('Meet John', 13), array('MT Meeting', 16));
            foreach ($events as $e) {
                $event = new \GO\Calendar\Model\Event();
                $event->name = $e[0];
                $event->location = "ACME NY Office";
                $event->start_time = \GO\Base\Util\Date::date_add(\GO\Base\Util\Date::clear_time($time, $e[1]), 1);
                $event->end_time = $event->start_time + 3600;
                $event->user_id = $linda->id;
                $event->calendar_id = \GO\Calendar\Model\Calendar::model()->getDefault($linda)->id;
                $event->save();
                $participant = new \GO\Calendar\Model\Participant();
                $participant->is_organizer = true;
                $participant->setContact($linda->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($demo->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($john);
                $event->addParticipant($participant);
                $john->link($event);
            }
            $events = array(array('Rocket testing', 8), array('Blast impact test', 15), array('Test range extender', 19));
            foreach ($events as $e) {
                $event = new \GO\Calendar\Model\Event();
                $event->name = $e[0];
                $event->location = "ACME Testing fields";
                $event->start_time = \GO\Base\Util\Date::date_add(\GO\Base\Util\Date::clear_time(time(), $e[1]), 1);
                $event->end_time = $event->start_time + 3600;
                $event->user_id = $linda->id;
                $event->calendar_id = \GO\Calendar\Model\Calendar::model()->getDefault($linda)->id;
                $event->save();
                $participant = new \GO\Calendar\Model\Participant();
                $participant->is_organizer = true;
                $participant->setContact($linda->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($demo->createContact());
                $event->addParticipant($participant);
                $participant = new \GO\Calendar\Model\Participant();
                $participant->setContact($john);
                $event->addParticipant($participant);
                $john->link($event);
            }
            $view = new \GO\Calendar\Model\View();
            $view->name = \GO::t('group_everyone');
            if ($view->save()) {
                $view->addManyMany('groups', \GO::config()->group_everyone);
                //share view
                $view->acl->addGroup(\GO::config()->group_internal);
            }
            $view = new \GO\Calendar\Model\View();
            $view->name = \GO::t('group_everyone') . ' (' . \GO::t('merge', 'calendar') . ')';
            $view->merge = true;
            $view->owncolor = true;
            if ($view->save()) {
                $view->addManyMany('groups', \GO::config()->group_everyone);
                //share view
                $view->acl->addGroup(\GO::config()->group_internal);
            }
            //resource groups
            $resourceGroup = \GO\Calendar\Model\Group::model()->findSingleByAttribute('name', "Meeting rooms");
            if (!$resourceGroup) {
                $resourceGroup = new \GO\Calendar\Model\Group();
                $resourceGroup->name = "Meeting rooms";
                $resourceGroup->save();
                //$resourceGroup->acl->addGroup(\GO::config()->group_internal);
            }
            $resourceCalendar = \GO\Calendar\Model\Calendar::model()->findSingleByAttribute('name', 'Road Runner Room');
            if (!$resourceCalendar) {
                $resourceCalendar = new \GO\Calendar\Model\Calendar();
                $resourceCalendar->group_id = $resourceGroup->id;
                $resourceCalendar->name = 'Road Runner Room';
                $resourceCalendar->save();
                $resourceCalendar->acl->addGroup(\GO::config()->group_internal);
            }
            $resourceCalendar = \GO\Calendar\Model\Calendar::model()->findSingleByAttribute('name', 'Don Coyote Room');
            if (!$resourceCalendar) {
                $resourceCalendar = new \GO\Calendar\Model\Calendar();
                $resourceCalendar->group_id = $resourceGroup->id;
                $resourceCalendar->name = 'Don Coyote Room';
                $resourceCalendar->save();
                $resourceCalendar->acl->addGroup(\GO::config()->group_internal);
            }
            //setup elmer as a resource admin
            $resourceGroup->addManyMany('admins', $elmer->id);
        }
        if (\GO::modules()->tasks) {
            $task = new \GO\Tasks\Model\Task();
            $task->tasklist_id = \GO\Tasks\Model\Tasklist::model()->getDefault($demo)->id;
            $task->name = 'Feed the dog';
            $task->start_time = time();
            $task->due_time = \GO\Base\Util\Date::date_add(time(), 2);
            $task->save();
            $task = new \GO\Tasks\Model\Task();
            $task->tasklist_id = \GO\Tasks\Model\Tasklist::model()->getDefault($linda)->id;
            $task->name = 'Feed the dog';
            $task->start_time = time();
            $task->due_time = \GO\Base\Util\Date::date_add(time(), 1);
            $task->save();
            $task = new \GO\Tasks\Model\Task();
            $task->tasklist_id = \GO\Tasks\Model\Tasklist::model()->getDefault($elmer)->id;
            $task->name = 'Feed the dog';
            $task->start_time = time();
            $task->due_time = \GO\Base\Util\Date::date_add(time(), 1);
            $task->save();
            $task = new \GO\Tasks\Model\Task();
            $task->tasklist_id = \GO\Tasks\Model\Tasklist::model()->getDefault($demo)->id;
            $task->name = 'Prepare meeting';
            $task->start_time = time();
            $task->due_time = \GO\Base\Util\Date::date_add(time(), 1);
            $task->save();
            $task->link($wile);
            $task->link($event);
            $task = new \GO\Tasks\Model\Task();
            $task->tasklist_id = \GO\Tasks\Model\Tasklist::model()->getDefault($linda)->id;
            $task->name = 'Prepare meeting';
            $task->start_time = time();
            $task->due_time = \GO\Base\Util\Date::date_add(time(), 1);
            $task->save();
            $task->link($wile);
            $task->link($event);
            $task = new \GO\Tasks\Model\Task();
            $task->tasklist_id = \GO\Tasks\Model\Tasklist::model()->getDefault($elmer)->id;
            $task->name = 'Prepare meeting';
            $task->start_time = time();
            $task->due_time = \GO\Base\Util\Date::date_add(time(), 1);
            $task->save();
            $task->link($wile);
            $task->link($event);
        }
        if (\GO::modules()->billing) {
            $rocket = \GO\Billing\Model\Product::model()->findSingleByAttribute('article_id', '12345');
            if (!$rocket) {
                $rocket = new \GO\Billing\Model\Product();
                $rocket->article_id = 12345;
                $rocket->supplier_company_id = $acme->id;
                $rocket->unit = 'pcs';
                $rocket->cost_price = 1000;
                $rocket->list_price = 2999.99;
                $rocket->total_price = 2999.99;
                $rocket->vat = 0;
                if (!$rocket->save()) {
                    var_dump($rocket->getValidationErrors());
                }
                $lang = new \GO\Billing\Model\ProductLanguage();
                $lang->language_id = 1;
                $lang->product_id = $rocket->id;
                $lang->name = 'Master Rocket 1000';
                $lang->description = 'Master Rocket 1000. The ultimate rocket to blast rocky mountains.';
                $lang->save();
            }
            $rocketLauncher = \GO\Billing\Model\Product::model()->findSingleByAttribute('article_id', '234567');
            if (!$rocketLauncher) {
                $rocketLauncher = new \GO\Billing\Model\Product();
                $rocketLauncher->article_id = 234567;
                $rocketLauncher->supplier_company_id = $acme->id;
                $rocketLauncher->unit = 'pcs';
                $rocketLauncher->cost_price = 3000;
                $rocketLauncher->list_price = 8999.99;
                $rocketLauncher->total_price = 8999.99;
                $rocketLauncher->vat = 0;
                if (!$rocketLauncher->save()) {
                    var_dump($rocket->getValidationErrors());
                }
                $lang = new \GO\Billing\Model\ProductLanguage();
                $lang->language_id = 1;
                $lang->product_id = $rocketLauncher->id;
                $lang->name = 'Rocket Launcher 1000';
                $lang->description = 'Rocket Launcher 1000. Required to launch rockets.';
                $lang->save();
            }
            $books = \GO\Billing\Model\Book::model()->find();
            foreach ($books as $book) {
                //give demo access
                $book->acl->addUser($demo->id, \GO\Base\Model\Acl::WRITE_PERMISSION);
                $book->acl->addUser($elmer->id, \GO\Base\Model\Acl::WRITE_PERMISSION);
                $order = new \GO\Billing\Model\Order();
                $order->book_id = $book->id;
                $order->btime = time();
                $order->setCustomerFromContact($john);
                $order->setCustomerFromCompany($company);
                $order->save();
                $order->addProduct($rocketLauncher, 1);
                $order->addProduct($rocket, 4);
                $status = $book->statuses(\GO\Base\Db\FindParams::newInstance()->single());
                $order->status_id = $status->id;
                $order->syncItems();
                $order = new \GO\Billing\Model\Order();
                $order->book_id = $book->id;
                $order->btime = time();
                $order->setCustomerFromContact($wile);
                $order->setCustomerFromCompany($acme);
                $order->save();
                $order->addProduct($rocketLauncher, 1);
                $order->addProduct($rocket, 10);
                $status = $book->statuses(\GO\Base\Db\FindParams::newInstance()->single());
                $order->status_id = $status->id;
                $order->syncItems();
            }
        }
        if (\GO::modules()->tickets) {
            $ticket = new \GO\Tickets\Model\Ticket();
            $ticket->subject = 'Malfunctioning rockets';
            $ticket->setFromContact($wile);
            if (!$ticket->save()) {
                var_dump($ticket->getValidationErrors());
                exit;
            }
            $message = new \GO\Tickets\Model\Message();
            $message->sendEmail = false;
            $message->content = "My rocket always circles back right at me? How do I aim right?";
            $message->is_note = false;
            $message->user_id = 0;
            $ticket->addMessage($message);
            //elmer picks up the ticket
            $ticket->agent_id = $elmer->id;
            $ticket->save();
            //make elmer and demo a ticket agent
            $ticket->type->acl->addUser($elmer->id, \GO\Base\Model\Acl::MANAGE_PERMISSION);
            $ticket->type->acl->addUser($demo->id, \GO\Base\Model\Acl::MANAGE_PERMISSION);
            $message = new \GO\Tickets\Model\Message();
            $message->sendEmail = false;
            $message->content = "Haha, good thing he doesn't know Accelleratii Incredibus designed this rocket and he can't read this note.";
            $message->is_note = true;
            $message->user_id = $elmer->id;
            $ticket->addMessage($message);
            $message = new \GO\Tickets\Model\Message();
            $message->sendEmail = false;
            $message->content = "Gee I don't know how that can happen. I'll send you some new ones!";
            $message->is_note = false;
            $message->status_id = \GO\Tickets\Model\Ticket::STATUS_CLOSED;
            $message->has_status = true;
            $message->user_id = $elmer->id;
            $ticket->addMessage($message);
            $ticket = new \GO\Tickets\Model\Ticket();
            $ticket->subject = 'Can I speed up my rockets?';
            $ticket->setFromContact($wile);
            $ticket->ctime = $ticket->mtime = \GO\Base\Util\Date::date_add(time(), -2);
            if (!$ticket->save()) {
                var_dump($ticket->getValidationErrors());
                exit;
            }
            $message = new \GO\Tickets\Model\Message();
            $message->sendEmail = false;
            $message->content = "The rockets are too slow to hit my fast moving target. Is there a way to speed them up?";
            $message->is_note = false;
            $message->user_id = 0;
            $message->ctime = $message->mtime = \GO\Base\Util\Date::date_add(time(), -2);
            $ticket->addMessage($message);
            //elmer picks up the ticket
            //			$ticket->agent_id=$elmer->id;
            //			$ticket->save();
            $message = new \GO\Tickets\Model\Message();
            $message->sendEmail = false;
            $message->content = "Please respond faster. Can't you see this ticket is marked in red?";
            $message->is_note = false;
            $message->user_id = 0;
            $ticket->addMessage($message);
            if (!\GO::modules()->isInstalled('site') && \GO::modules()->isAvailable('site')) {
                $module = new \GO\Base\Model\Module();
                $module->id = 'site';
                $module->save();
            }
            if (!\GO::modules()->isInstalled('defaultsite') && \GO::modules()->isAvailable('defaultsite')) {
                $module = new \GO\Base\Model\Module();
                $module->id = 'defaultsite';
                $module->save();
            }
            $settings = \GO\Tickets\Model\Settings::model()->findModel();
            $settings->enable_external_page = true;
            $settings->use_alternative_url = true;
            $settings->allow_anonymous = true;
            $settings->alternative_url = \GO::config()->full_url . 'modules/site/index.php?r=tickets/externalpage/ticket';
            $settings->save();
            if (\GO::modules()->summary) {
                $title = "Submit support ticket";
                $announcement = \GO\Summary\Model\Announcement::model()->findSingleByAttribute('title', $title);
                if (!$announcement) {
                    $newTicketUrl = \GO::config()->full_url . 'modules/site/index.php?r=tickets/externalpage/newTicket';
                    $announcement = new \GO\Summary\Model\Announcement();
                    $announcement->title = $title;
                    $announcement->content = 'Anyone can submit tickets to the support system here:' . '<br /><br /><a href="' . $newTicketUrl . '">' . $newTicketUrl . '</a><br /><br />Anonymous ticket posting can be disabled in the ticket module settings.';
                    if ($announcement->save()) {
                        $announcement->acl->addGroup(\GO::config()->group_everyone);
                    }
                }
            }
        }
        if (\GO::modules()->notes) {
            $category = \GO\Notes\Model\Category::model()->findSingleByAttribute('name', \GO::t('general', 'notes'));
            if (!$category) {
                $category = new \GO\Notes\Model\Category();
                $category->name = \GO::t('general', 'notes');
                $category->save();
                $category->acl->addGroup(\GO::config()->group_everyone, \GO\Base\Model\Acl::READ_PERMISSION);
            }
            $note = new \GO\Notes\Model\Note();
            $note->user_id = $elmer->id;
            //$category = \GO\Notes\Model\Category::model()->getDefault($elmer);
            $note->category_id = $category->id;
            $note->name = "Laws and rules";
            $note->content = 'As in other cartoons, the Road Runner and the coyote follow the laws of cartoon physics. For example, the Road Runner has the ability to enter the painted image of a cave, while the coyote cannot (unless there is an opening through which he can fall). Sometimes, however, this is reversed, and the Road Runner can burst through a painting of a broken bridge and continue on his way, while the Coyote will instead enter the mirage painting and fall down the precipice of the cliff where the bridge is out. Sometimes the coyote is allowed to hang in midair until he realizes that he is about to plummet into a chasm (a process occasionally referred to elsewhere as Road-Runnering or Wile E. Coyote moment). The coyote can overtake rocks (or cannons) which fall earlier than he does, and end up being squashed by them. If a chase sequence happens upon a cliff, the Road Runner is not affected by gravity, whereas the Coyote will realize his error eventually and fall to the ground below. A chase sequence that happens upon railroad tracks will always result in the Coyote being run over by a train. If the Coyote uses an explosive (for instance, dynamite) that is triggered by a mechanism that is supposed to force the explosive in a forward motion toward its target, the actual mechanism itself will always shoot forward, leaving the explosive behind to detonate in the Coyote\'s face. Similarly, a complex apparatus that is supposed to propel an object like a boulder or steel ball forward, or trigger a trap, will not work on the Road Runner, but always will on the Coyote. For instance, the Road Runner can jump up and down on the trigger of a large animal trap and eat bird seed off from it, going completely unharmed and not setting off the trap; when the Coyote places the tiniest droplet of oil on the trigger, the trap snaps shut on him without fail. At certain times, the Coyote may don an exquisite Acme costume or propulsion device that briefly allows him to catch up to the Road Runner. This will always result in him losing track of his proximity to large cliffs or walls, and the Road Runner will dart around an extremely sharp turn on a cliff, but the Coyote will rocket right over the edge and fall to the ground.

In his book Chuck Amuck: The Life and Times Of An Animated Cartoonist,[13] Chuck Jones claimed that he and the artists behind the Road Runner and Wile E. cartoons adhered to some simple but strict rules:

The Road Runner cannot harm the Coyote except by going "beep, beep."
No outside force can harm the Coyote — only his own ineptitude or the failure of Acme products. Trains and trucks were the exception from time to time.
The Coyote could stop anytime — if he were not a fanatic. (Repeat: "A fanatic is one who redoubles his effort when he has forgotten his aim." — George Santayana).
Dialogue must never be used, except "beep, beep" and yowling in pain. (This rule, however, was violated in some cartoons.)
The Road Runner must stay on the road — for no other reason than that he\'s a roadrunner. This rule was broken in Beep, Beep, in a sequence where Wile E. chased the Road Runner into a cactus mine. And also in Fastest with the Mostestwhen Coyote lures Road Runner to the edge of a cliff.
All action must be confined to the natural environment of the two characters — the southwest American desert.
All (or at least almost all) tools, weapons, or mechanical conveniences must be obtained from the Acme Corporation. There were sometimes exceptions when the Coyote obtained other items from the desert such as boulders to use in his attempts.
Whenever possible, make gravity the Coyote\'s greatest enemy (e.g., falling off a cliff).
The Coyote is always more humiliated than harmed by his failures.
The audience\'s sympathy must remain with the Coyote.
The Coyote is not allowed to catch or eat the Road Runner, unless he escapes from the grasp. (The robot that the Coyote created in The Solid Tin Coyote caught the Road Runner so this does not break this rule. The Coyote does catch the Road Runner in Soup or Sonic but is too small to eat him. There is also two CGI shorts on The Looney Tunes Show were he caught the bird, but was not able to eat him because the Road Runner got away in both shorts.)';
            $note->save();
            $note->link($john);
            $note = new \GO\Notes\Model\Note();
            $note->user_id = $demo->id;
            $note->category_id = $category->id;
            $note->name = "Wile E. Coyote and Bugs Bunny";
            $note->content = 'Wile E. Coyote has also unsuccessfully attempted to catch and eat Bugs Bunny in another series of cartoons. In these cartoons, the coyote takes on the guise of a self-described "super genius" and speaks with a smooth, generic upper-class accent provided by Mel Blanc. While he is incredibly intelligent, he is limited by technology and his own short-sighted arrogance, and is thus often easily outsmarted, a somewhat physical symbolism of "street smarts" besting "book smarts".

In one short (Hare-Breadth Hurry, 1963), Bugs Bunny — with the help of "speed pills" — even stands in for Road Runner, who has "sprained a giblet", and carries out the duties of outsmarting the hungry scavenger. That is the only Bugs Bunny/Wile E. Coyote short in which the coyote does not speak. As usual Wile E. Coyote ends up falling down a canyon. In a later, made-for-TV short, which had a young Elmer Fudd chasing a young Bugs Bunny, Elmer also falls down a canyon. On the way down he is overtaken by Wile E. Coyote who shows a sign telling Elmer to get out of the way for someone who is more experienced in falling.';
            $note->save();
            $note->link($wile);
        }
        if (\GO::modules()->summary) {
            $title = "Welcome to " . \GO::config()->product_name;
            $announcement = \GO\Summary\Model\Announcement::model()->findSingleByAttribute('title', $title);
            if (!$announcement) {
                $announcement = new \GO\Summary\Model\Announcement();
                $announcement->title = $title;
                $announcement->content = 'This is a demo announcements that administrators can set.<br />Have a look around.<br /><br />We hope you\'ll enjoy Group-Office as much as we do!';
                if ($announcement->save()) {
                    $announcement->acl->addGroup(\GO::config()->group_everyone);
                }
            }
        }
        if (\GO::modules()->files) {
            $demoHome = \GO\Files\Model\Folder::model()->findHomeFolder($demo);
            $file = new \GO\Base\Fs\File(\GO::modules()->files->path . 'install/templates/empty.docx');
            $copy = $file->copy($demoHome->fsFolder);
            $file = new \GO\Base\Fs\File(\GO::modules()->files->path . 'install/templates/empty.odt');
            $copy = $file->copy($demoHome->fsFolder);
            $file = new \GO\Base\Fs\File(\GO::modules()->addressbook->path . 'install/Demo letter.docx');
            $copy = $file->copy($demoHome->fsFolder);
            $file = new \GO\Base\Fs\File(\GO::modules()->addressbook->path . 'install/wecoyote.png');
            $copy = $file->copy($demoHome->fsFolder);
            $file = new \GO\Base\Fs\File(\GO::modules()->addressbook->path . 'install/noperson.jpg');
            $copy = $file->copy($demoHome->fsFolder);
            //add files to db.
            $demoHome->syncFilesystem();
        }
        if (\GO::modules()->projects) {
            $templates = \GO\Projects\Model\Template::model()->find();
            $folderTemplate = $templates->fetch();
            $projectTemplate = $templates->fetch();
            $status = \GO\Projects\Model\Status::model()->findSingle();
            $type = \GO\Projects\Model\Type::model()->findSingleByAttribute('name', 'Demo');
            if (!$type) {
                $type = new \GO\Projects\Model\Type();
                $type->name = 'Demo';
                if (!$type->save()) {
                    var_dump($type->getValidationErrors());
                    exit;
                }
                $type->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::WRITE_PERMISSION);
            }
            $folderProject = \GO\Projects\Model\Project::model()->findSingleByAttribute('name', 'Demo');
            if (!$folderProject) {
                $folderProject = new \GO\Projects\Model\Project();
                $folderProject->name = 'Demo';
                $folderProject->description = 'Just a placeholder for sub projects.';
                $folderProject->template_id = $folderTemplate->id;
                $folderProject->type_id = $type->id;
                $folderProject->status_id = $status->id;
                if (!$folderProject->save()) {
                    var_dump($folderProject->getValidationErrors());
                    exit;
                }
            }
            $rocketProject = \GO\Projects\Model\Project::model()->findSingleByAttribute('name', '[001] Develop Rocket 2000');
            if (!$rocketProject) {
                $rocketProject = new \GO\Projects\Model\Project();
                $rocketProject->type_id = $type->id;
                $rocketProject->status_id = $status->id;
                $rocketProject->name = '[001] Develop Rocket 2000';
                $rocketProject->description = 'Better range and accuracy';
                $rocketProject->template_id = $projectTemplate->id;
                $rocketProject->parent_project_id = $folderProject->id;
                $rocketProject->start_time = time();
                $rocketProject->due_time = \GO\Base\Util\Date::date_add(time(), 0, 1);
                $rocketProject->company_id = $acme->id;
                $rocketProject->contact_id = $wile->id;
                $rocketProject->save();
            }
            $launcherProject = \GO\Projects\Model\Project::model()->findSingleByAttribute('name', '[001] Develop Rocket Launcher');
            if (!$launcherProject) {
                $launcherProject = new \GO\Projects\Model\Project();
                $launcherProject->type_id = $type->id;
                $launcherProject->status_id = $status->id;
                $launcherProject->name = '[001] Develop Rocket Launcher';
                $launcherProject->description = 'Better range and accuracy';
                $launcherProject->template_id = $projectTemplate->id;
                $launcherProject->parent_project_id = $folderProject->id;
                $launcherProject->start_time = time();
                $launcherProject->due_time = \GO\Base\Util\Date::date_add(time(), 0, 1);
                $launcherProject->company_id = $acme->id;
                $launcherProject->contact_id = $wile->id;
                $launcherProject->save();
            }
        }
        if (\GO::modules()->projects2) {
            if (!\GO\Projects2\Model\Employee::model()->count()) {
                $employee = new \GO\Projects2\Model\Employee();
                $employee->user_id = $elmer->id;
                $employee->external_fee = 120;
                $employee->internal_fee = 60;
                $employee->save();
                $employee = new \GO\Projects2\Model\Employee();
                $employee->user_id = $demo->id;
                $employee->external_fee = 80;
                $employee->internal_fee = 40;
                $employee->save();
                $employee = new \GO\Projects2\Model\Employee();
                $employee->user_id = $linda->id;
                $employee->external_fee = 90;
                $employee->internal_fee = 45;
                $employee->save();
            } else {
                $employee = \GO\Projects2\Model\Employee::model()->findSingle();
            }
            $templates = \GO\Projects2\Model\Template::model()->find();
            $folderTemplate = $templates->fetch();
            $projectTemplate = $templates->fetch();
            $status = \GO\Projects2\Model\Status::model()->findSingle();
            $type = \GO\Projects2\Model\Type::model()->findSingleByAttribute('name', 'Demo');
            if (!$type) {
                $type = new \GO\Projects2\Model\Type();
                $type->name = 'Demo';
                if (!$type->save()) {
                    var_dump($type->getValidationErrors());
                    exit;
                }
                $type->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::WRITE_PERMISSION);
            }
            $folderProject = \GO\Projects2\Model\Project::model()->findSingleByAttribute('name', 'Demo');
            if (!$folderProject) {
                $folderProject = new \GO\Projects2\Model\Project();
                $folderProject->name = 'Demo';
                $folderProject->start_time = time();
                $folderProject->description = 'Just a placeholder for sub projects.';
                $folderProject->template_id = $folderTemplate->id;
                $folderProject->type_id = $type->id;
                $folderProject->status_id = $status->id;
                if (!$folderProject->save()) {
                    var_dump($folderProject->getValidationErrors());
                    exit;
                }
            }
            $rocketProject = \GO\Projects2\Model\Project::model()->findSingleByAttribute('name', '[001] Develop Rocket 2000');
            if (!$rocketProject) {
                $rocketProject = new \GO\Projects2\Model\Project();
                $rocketProject->type_id = $type->id;
                $rocketProject->status_id = $status->id;
                $rocketProject->name = '[001] Develop Rocket 2000';
                $rocketProject->description = 'Better range and accuracy';
                $rocketProject->template_id = $projectTemplate->id;
                $rocketProject->parent_project_id = $folderProject->id;
                $rocketProject->start_time = time();
                $rocketProject->due_time = \GO\Base\Util\Date::date_add(time(), 0, 1);
                $rocketProject->company_id = $acme->id;
                $rocketProject->contact_id = $wile->id;
                //				$rocketProject->budget=20000;
                $rocketProject->save();
                $resource = new \GO\Projects2\Model\Resource();
                $resource->project_id = $rocketProject->id;
                $resource->user_id = $demo->id;
                $resource->budgeted_units = 100;
                $resource->external_fee = 80;
                $resource->internal_fee = 40;
                $resource->save();
                $resource = new \GO\Projects2\Model\Resource();
                $resource->project_id = $rocketProject->id;
                $resource->user_id = $elmer->id;
                $resource->budgeted_units = 16;
                $resource->external_fee = 120;
                $resource->internal_fee = 60;
                $resource->save();
                $resource = new \GO\Projects2\Model\Resource();
                $resource->project_id = $rocketProject->id;
                $resource->user_id = $linda->id;
                $resource->budgeted_units = 16;
                $resource->external_fee = 90;
                $resource->internal_fee = 45;
                $resource->save();
                $groupTask = new \GO\Projects2\Model\Task();
                $groupTask->project_id = $rocketProject->id;
                $groupTask->description = 'Design';
                $groupTask->duration = 8 * 60;
                $groupTask->user_id = $demo->id;
                $groupTask->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'Functional design';
                $task->percentage_complete = 100;
                $task->duration = 8 * 60;
                $task->user_id = $demo->id;
                $task->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'Technical design';
                $task->percentage_complete = 50;
                $task->duration = 8 * 60;
                $task->user_id = $demo->id;
                $task->save();
                $groupTask = new \GO\Projects2\Model\Task();
                $groupTask->project_id = $rocketProject->id;
                $groupTask->description = 'Implementation';
                $groupTask->duration = 8 * 60;
                $groupTask->user_id = $demo->id;
                $groupTask->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'Models';
                $task->duration = 4 * 60;
                $task->user_id = $demo->id;
                $task->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'Controllers';
                $task->duration = 2 * 60;
                $task->user_id = $demo->id;
                $task->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'Views';
                $task->duration = 6 * 60;
                $task->user_id = $demo->id;
                $task->save();
                $groupTask = new \GO\Projects2\Model\Task();
                $groupTask->project_id = $rocketProject->id;
                $groupTask->description = 'Testing';
                $groupTask->duration = 8 * 60;
                $groupTask->user_id = $demo->id;
                $groupTask->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'GUI';
                $task->duration = 8 * 60;
                $task->user_id = $elmer->id;
                $task->save();
                $task = new \GO\Projects2\Model\Task();
                $task->parent_id = $groupTask->id;
                $task->project_id = $rocketProject->id;
                $task->description = 'Security';
                $task->duration = 8 * 60;
                $task->user_id = $elmer->id;
                $task->save();
                $expenseBudget = new \GO\Projects2\Model\ExpenseBudget();
                $expenseBudget->description = 'Machinery';
                $expenseBudget->nett = 10000;
                $expenseBudget->project_id = $rocketProject->id;
                $expenseBudget->save();
                $expense = new \GO\Projects2\Model\Expense();
                $expense->description = 'Rocket fuel';
                $expense->project_id = $rocketProject->id;
                $expense->nett = 3000;
                $expense->save();
                $expense = new \GO\Projects2\Model\Expense();
                $expense->expense_budget_id = $expenseBudget->id;
                $expense->description = 'Fuse machine';
                $expense->project_id = $rocketProject->id;
                $expense->nett = 2000;
                $expense->save();
            }
            $launcherProject = \GO\Projects2\Model\Project::model()->findSingleByAttribute('name', '[001] Develop Rocket Launcher');
            if (!$launcherProject) {
                $launcherProject = new \GO\Projects2\Model\Project();
                $launcherProject->type_id = $type->id;
                $launcherProject->status_id = $status->id;
                $launcherProject->name = '[001] Develop Rocket Launcher';
                $launcherProject->description = 'Better range and accuracy';
                $launcherProject->template_id = $projectTemplate->id;
                $launcherProject->parent_project_id = $folderProject->id;
                $launcherProject->start_time = time();
                $launcherProject->due_time = \GO\Base\Util\Date::date_add(time(), 0, 1);
                $launcherProject->company_id = $acme->id;
                $launcherProject->contact_id = $wile->id;
                $launcherProject->save();
                $resource = new \GO\Projects2\Model\Resource();
                $resource->project_id = $launcherProject->id;
                $resource->user_id = $demo->id;
                $resource->external_fee = 80;
                $resource->internal_fee = 40;
                $resource->budgeted_units = 16;
                $resource->save();
            }
        }
        if (\GO::modules()->bookmarks) {
            $category = \GO\Bookmarks\Model\Category::model()->findSingleByAttribute('name', \GO::t('general', 'bookmarks'));
            if (!$category) {
                $category = new \GO\Bookmarks\Model\Category();
                $category->name = \GO::t('general', 'bookmarks');
                $category->save();
                $category->acl->addGroup(\GO::config()->group_internal, \GO\Base\Model\Acl::READ_PERMISSION);
            }
            $bookmark = \GO\Bookmarks\Model\Bookmark::model()->findSingleByAttribute('name', 'Google Search');
            if (!$bookmark) {
                $bookmark = new \GO\Bookmarks\Model\Bookmark();
                $bookmark->category_id = $category->id;
                $bookmark->name = 'Google Search';
                $bookmark->content = 'http://www.google.com';
                $bookmark->logo = 'icons/viewmag.png';
                $bookmark->public_icon = true;
                $bookmark->description = 'Search the web';
                $bookmark->open_extern = true;
                $bookmark->save();
            }
            $bookmark = \GO\Bookmarks\Model\Bookmark::model()->findSingleByAttribute('name', 'Wikipedia');
            if (!$bookmark) {
                $bookmark = new \GO\Bookmarks\Model\Bookmark();
                $bookmark->category_id = $category->id;
                $bookmark->name = 'Wikipedia';
                $bookmark->content = 'http://www.wikipedia.com';
                $bookmark->logo = 'icons/agt_web.png';
                $bookmark->public_icon = true;
                $bookmark->description = 'The Free Encyclopedia';
                $bookmark->behave_as_module = true;
                $bookmark->save();
            }
        }
        if (\GO::modules()->postfixadmin) {
            $domainModel = \GO\Postfixadmin\Model\Domain::model()->findSingleByAttribute('domain', 'acmerpp.demo');
            if (!$domainModel) {
                $domainModel = new \GO\Postfixadmin\Model\Domain();
                $domainModel->domain = 'acmerpp.demo';
                $domainModel->save();
            }
            $this->_createMailbox($domainModel, $demo);
            $this->_createMailbox($domainModel, $elmer);
            $this->_createMailbox($domainModel, $linda);
        }
        if (\GO::modules()->savemailas) {
            //link some demo mails
            $mimeFile = new \GO\Base\Fs\File(\GO::modules()->savemailas->path . 'install/demo.eml');
            \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $wile);
            \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $john);
            if (\GO::modules()->projects) {
                \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $rocketProject);
                \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $launcherProject);
            }
            $mimeFile = new \GO\Base\Fs\File(\GO::modules()->savemailas->path . 'install/demo2.eml');
            \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $wile);
            \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $john);
            if (\GO::modules()->projects) {
                \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $rocketProject);
                \GO\Savemailas\Model\LinkedEmail::model()->createFromMimeFile($mimeFile, $launcherProject);
            }
        }
        //useful for other modules to create stuff
        $this->fireEvent('demodata', array('users' => array('demo' => $demo, 'linda' => $linda, 'elmer' => $elmer)));
        if (\GO::modules()->demodata) {
            \GO::modules()->demodata->delete();
        }
        if (!$this->isCli()) {
            //login as demo
            \GO::session()->restart();
            \GO::session()->setCurrentUser($demo->id);
            $this->redirect();
        }
    }
Пример #9
0
<?php

$calendar = \GO\Calendar\Model\Calendar::model()->getDefault(\GO::user());
$settings = \GO\Calendar\Model\Settings::model()->getDefault(\GO::user());
if ($calendar) {
    $GO_SCRIPTS_JS .= 'GO.calendar.defaultCalendar = ' . json_encode($calendar->getAttributes()) . ';';
}
$GO_SCRIPTS_JS .= 'GO.calendar.categoryRequired="' . \GO\Calendar\CalendarModule::commentsRequired() . '";';
$GO_SCRIPTS_JS .= 'GO.calendar.disablePublishing=' . (!empty(\GO::config()->calendar_disable_publishing) ? 'true' : 'false') . ';';
if ($settings) {
    $GO_SCRIPTS_JS .= 'GO.calendar.showStatuses=' . ($settings->show_statuses ? 'true;' : 'false;');
}
Пример #10
0
 /**
  * Find an event based on uuid field for a user. Either user_id or calendar_id
  * must be supplied.
  * 
  * Optionally exceptionDate can be specified to find a specific exception.
  * 
  * @param string $uuid
  * @param int $user_id
  * @param int $calendar_id
  * @param int $exceptionDate
  * @return Event 
  */
 public function findByUuid($uuid, $user_id, $calendar_id = 0, $exceptionDate = false)
 {
     $whereCriteria = \GO\Base\Db\FindCriteria::newInstance()->addCondition('uuid', $uuid);
     $params = \GO\Base\Db\FindParams::newInstance()->ignoreAcl()->single();
     if (!$calendar_id) {
         $joinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addCondition('calendar_id', 'c.id', '=', 't', true, true)->addCondition('user_id', $user_id, '=', 'c');
         $params->join(Calendar::model()->tableName(), $joinCriteria, 'c');
     } else {
         $whereCriteria->addCondition('calendar_id', $calendar_id);
     }
     if ($exceptionDate) {
         //must be an exception and start on the must start on the exceptionTime
         $exceptionJoinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addCondition('id', 'e.exception_event_id', '=', 't', true, true);
         $params->join(Exception::model()->tableName(), $exceptionJoinCriteria, 'e');
         $dayStart = \GO\Base\Util\Date::clear_time($exceptionDate);
         $dayEnd = \GO\Base\Util\Date::date_add($dayStart, 1);
         $dateCriteria = \GO\Base\Db\FindCriteria::newInstance()->addCondition('time', $dayStart, '>=', 'e')->addCondition('time', $dayEnd, '<', 'e');
         $whereCriteria->mergeWith($dateCriteria);
         //			//the code below only find exceptions on the same day which is wrong
         //			$whereCriteria->addCondition('exception_for_event_id', 0,'>');
         //
         //			$dayStart = \GO\Base\Util\Date::clear_time($exceptionDate);
         //			$dayEnd = \GO\Base\Util\Date::date_add($dayStart,1);
         //
         //			$dateCriteria = \GO\Base\Db\FindCriteria::newInstance()
         //							->addCondition('start_time', $dayStart, '>=')
         //							->addCondition('start_time', $dayEnd, '<','t',false);
         //
         //			$whereCriteria->mergeWith($dateCriteria);
     } else {
         $whereCriteria->addCondition('exception_for_event_id', 0);
     }
     $params->criteria($whereCriteria);
     return $this->find($params);
 }
Пример #11
0
 /**
  * Get all today's events from the database.
  * 
  * @param \GO\base\Model\User $user
  * @return \GO\Calendar\Model\Event[]
  */
 private function _getEvents($user)
 {
     $defaultCalendar = \GO\Calendar\Model\Calendar::model()->getDefault($user);
     $todayStart = strtotime('today') + 1;
     $todayEnd = strtotime('tomorrow');
     if ($defaultCalendar) {
         $findParams = \GO\Base\Db\FindParams::newInstance()->select()->criteria(\GO\Base\Db\FindCriteria::newInstance()->addCondition('calendar_id', $defaultCalendar->id));
         $events = \GO\Calendar\Model\Event::model()->findCalculatedForPeriod($findParams, $todayStart, $todayEnd);
         return $events;
         //->fetchAll();
     } else {
         return array();
     }
 }
Пример #12
0
 private function _loadCurrentCalendar($calendarId)
 {
     if (empty($calendarId)) {
         throw new FileNotFoundException();
     }
     $this->_calendar = \GO\Calendar\Model\Calendar::model()->findByPk($calendarId);
 }
Пример #13
0
 /**
  * Fill the response array with the events of the given calendar between 
  * the start and end time
  * 
  * @param array $response
  * @param \GO\Calendar\Model\Calendar $calendar
  * @param string $startTime
  * @param string $endTime
  * @return array 
  */
 private function _getEventResponseForPeriod($response, $calendar, $startTime, $endTime)
 {
     $resultCount = 0;
     // Get all the localEvent models between the given time period
     $events = $calendar->getEventsForPeriod(strtotime($startTime), strtotime($endTime));
     //		$this->_uuidEvents = array();
     // Loop through each event and prepare the view for it.
     foreach ($events as $event) {
         // Check for a double event, and merge them if they are double
         $key = $event->getUuid() . $event->getAlternateStartTime();
         //$event->getEvent()->location = $key;
         if (isset($this->_uuidEvents[$key])) {
             if (!empty(\GO::config()->calendar_disable_merge) || $event->getEvent()->calendar_id == $this->_uuidEvents[$key]->getEvent()->calendar_id) {
                 //this is an erroneous situation. events with the same start time and the same uuid may not appear in the same calendar.
                 //if we merge it then the user can't edit the events anymore.
                 $key .= $event->getEvent()->id;
                 $this->_uuidEvents[$key] = $event;
             } else {
                 $this->_uuidEvents[$key]->mergeWithEvent($event);
             }
         } else {
             //echo $event->getEvent()->name.' '.$key.', ';
             $this->_uuidEvents[$key] = $event;
         }
         //			$this->_uuidEvents[]=$event;
         // If you are showing more than one calendar, then change the display
         // color of the current event to the color of the calendar it belongs to.
         if ($response['calendar_count'] > 1) {
             $background = $calendar->getColor(\GO::user()->id);
             if (empty($background)) {
                 $background = $calendar->displayColor;
             }
             $event->setBackgroundColor($background);
         }
         // Set the id of the event, this is a count of the displayed events
         // in the view.
         //			$event->displayId = $response['count']++;
         $resultCount++;
         // Add one to the global result count;
     }
     //		foreach($this->_uuidEvents as $uuidEvent) { // Add the event to the results array
     //			$index = $this->_getIndex($response['results'],$uuidEvent->getAlternateStartTime(),$uuidEvent->getName());
     //			$response['results'][$index]=$uuidEvent->getResponseData();
     //			if ($uuidEvent->getEvent()->isResource())
     //				$response['results'][$index]['resourced_calendar_name'] = $uuidEvent->getEvent()->resourceGetEventCalendarName();
     //		}
     $response['count_events_only'] = $resultCount;
     // Set the count of the events
     return $response;
 }
Пример #14
0
 public function actionFreeBusyInfo($params)
 {
     $event_id = empty($params['event_id']) ? 0 : $params['event_id'];
     $date = getdate(\GO\Base\Util\Date::to_unixtime($params['date']));
     $daystart = mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']);
     $dayend = mktime(0, 0, 0, $date['mon'], $date['mday'] + 1, $date['year']);
     $response['results'] = array();
     $response['success'] = true;
     $merged_free_busy_participants = array();
     for ($i = 0; $i < 1440; $i += 15) {
         $merged_free_busy_participants[$i] = 0;
     }
     $merged_free_busy_all = array();
     for ($i = 0; $i < 1440; $i += 15) {
         $merged_free_busy_all[$i] = 0;
     }
     // Create Participants header row
     $row['name'] = '<b>' . \GO::t('participants', 'calendar') . '</b>';
     $row['email'] = '';
     $row['freebusy'] = array();
     for ($min = 0; $min < 1440; $min += 15) {
         $row['freebusy'][] = array('time' => date(\GO::user()->time_format, mktime(0, $min)), 'busy' => false);
     }
     $response['results'][] = $row;
     // Create a participant row for every participant
     if (!empty($params['participantData'])) {
         $participants = json_decode($params['participantData'], true);
         foreach ($participants as $row) {
             $row['freebusy'] = array();
             if (!empty($row['user_id'])) {
                 $user = \GO\Base\Model\User::model()->findByPk($row['user_id']);
                 if ($user) {
                     $participant = new \GO\Calendar\Model\Participant();
                     $participant->user_id = $user->id;
                     $participant->name = $user->name;
                     $participant->email = $user->email;
                     $participant->event_id = $event_id;
                     if ($participant->hasFreeBusyAccess()) {
                         $freebusy = $participant->getFreeBusyInfo($daystart, $dayend);
                         foreach ($freebusy as $min => $busy) {
                             if ($busy == 1) {
                                 $merged_free_busy_participants[$min] = 1;
                                 $merged_free_busy_all[$min] = 1;
                             }
                             $row['freebusy'][] = array('time' => date('G:i', mktime(0, $min)), 'busy' => $busy);
                         }
                     }
                 }
             }
             $response['results'][] = $row;
         }
     }
     // Create the together row
     $row['name'] = \GO::t('allTogetherForParticipants', 'calendar');
     $row['email'] = '';
     $row['freebusy'] = array();
     foreach ($merged_free_busy_participants as $min => $busy) {
         $row['freebusy'][] = array('time' => date(\GO::user()->time_format, mktime(0, $min)), 'busy' => $busy);
     }
     $response['results'][] = $row;
     // And now for the resources...
     $resource['name'] = '<b>' . \GO::t('resources', 'calendar') . '</b>';
     $resource['email'] = '';
     $resource['freebusy'] = array();
     for ($min = 0; $min < 1440; $min += 15) {
         $resource['freebusy'][] = array('time' => date(\GO::user()->time_format, mktime(0, $min)), 'busy' => false);
     }
     $response['results'][] = $resource;
     $merged_free_busy_resources = array();
     for ($i = 0; $i < 1440; $i += 15) {
         $merged_free_busy_resources[$i] = 0;
     }
     $resourceIds = json_decode($params['resourceIds']);
     if (empty($resourceIds)) {
         $resourceIds = array('-1');
     }
     $calendarsStmt = \GO\Calendar\Model\Calendar::model()->find(\GO\Base\Db\FindParams::newInstance()->criteria(\GO\Base\Db\FindCriteria::newInstance()->addInCondition('id', $resourceIds))->order('name', 'ASC'));
     foreach ($calendarsStmt as $resourceCalModel) {
         $resource['name'] = $resourceCalModel->name;
         $resource['email'] = $resourceCalModel->user->email;
         $resource['freebusy'] = array();
         $freebusy = $resourceCalModel->getFreeBusyInfo($daystart);
         foreach ($freebusy as $min => $busy) {
             if ($busy == 1) {
                 $merged_free_busy_resources[$min] = 1;
                 $merged_free_busy_all[$min] = 1;
             }
             $resource['freebusy'][] = array('time' => date('G:i', mktime(0, $min)), 'busy' => $busy);
         }
         $response['results'][] = $resource;
     }
     $resource['name'] = \GO::t('allTogetherForResources', 'calendar');
     $resource['email'] = '';
     $resource['freebusy'] = array();
     foreach ($merged_free_busy_resources as $min => $busy) {
         $resource['freebusy'][] = array('time' => date(\GO::user()->time_format, mktime(0, $min)), 'busy' => $busy);
     }
     $response['results'][] = $resource;
     $business['name'] = '<b>' . \GO::t('allTogether', 'calendar') . '</b>';
     $business['email'] = '';
     $business['freebusy'] = array();
     foreach ($merged_free_busy_all as $min => $busy) {
         $business['freebusy'][] = array('time' => date(\GO::user()->time_format, mktime(0, $min)), 'busy' => $busy);
     }
     $response['results'][] = $business;
     return $response;
 }
Пример #15
0
<?php

//require_once('../../../../GO.php');
//\GO::session()->runAsRoot();
if (\GO::modules()->isInstalled('projects')) {
    $fp = \GO\Base\Db\FindParams::newInstance()->ignoreAcl();
    $joinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addRawCondition('t.acl_id', 'p.acl_id');
    $fp->join('pm_types', $joinCriteria, 'p');
    $stmt = \GO\Calendar\Model\Calendar::model()->find($fp);
    foreach ($stmt as $calendar) {
        echo "Fixing " . $calendar->name . "\n";
        $oldAcl = $calendar->acl;
        $newAcl = $calendar->setNewAcl();
        $calendar->save();
        $oldAcl->copyPermissions($newAcl);
    }
}
Пример #16
0
<?php

echo "Converting existing categories from user to calendar\n";
//require_once('../../../../GO.php');
\GO::$ignoreAclPermissions = true;
$oldCategories = array();
$stmt = \GO\Calendar\Model\Category::model()->find();
while ($category = $stmt->fetch()) {
    if ($category->calendar_id != 0) {
        $oldCategories[] = $category->id;
        echo "Category {$category->name}\n";
        $calStmt = \GO\Calendar\Model\Calendar::model()->findByAttribute('user_id', $category->calendar_id);
        while ($calendar = $calStmt->fetch()) {
            try {
                // Create the new categories for each calendar
                $newCategory = new \GO\Calendar\Model\Category();
                $newCategory->name = $category->name;
                $newCategory->color = $category->color;
                $newCategory->calendar_id = $calendar->id;
                $newCategory->save();
                // Get all events that have the old category and change the category to the new one.
                $eventStmt = \GO\Calendar\Model\Event::model()->findByAttributes(array('calendar_id' => $calendar->id, 'category_id' => $category->id));
                while ($event = $eventStmt->fetch()) {
                    //echo "Update event $event->name\n";
                    $event->category_id = $newCategory->id;
                    $event->save();
                }
            } catch (\Exception $e) {
                echo $e->getMessage() . "\n";
            }
        }
Пример #17
0
 public function actionDay($date, $calendars)
 {
     $calendarIds = json_decode($calendars);
     $date = \GO\Base\Util\Date::clear_time($date);
     $start = $date - 1;
     $end = $date + 24 * 3600;
     $report = new \GO\Calendar\Reports\Day();
     foreach ($calendarIds as $id) {
         $calendar = \GO\Calendar\Model\Calendar::model()->findByPk($id);
         $events = $calendar->getEventsForPeriod($start, $end);
         if (!empty($calendar->tasklist)) {
             $tasklistId = $calendar->tasklist->id;
             $report->tasks = \GO\Tasks\Model\Task::model()->findByDate($date, $tasklistId)->fetchAll();
         }
         $report->setEvents($events);
         $report->render($date);
         $report->calendarName = $calendar->name;
     }
     $report->Output('day.pdf');
 }
Пример #18
0
 public function actionRemoveDuplicates($params)
 {
     $this->render('externalHeader');
     \GO::setMaxExecutionTime(300);
     \GO::setMemoryLimit(1024);
     $calendar = \GO\Calendar\Model\Calendar::model()->findByPk($params['calendar_id']);
     if (!$calendar) {
         throw new \GO\Base\Exception\NotFound();
     }
     File::setAllowDeletes(false);
     //VERY IMPORTANT:
     \GO\Files\Model\Folder::$deleteInDatabaseOnly = true;
     \GO::session()->closeWriting();
     //close writing otherwise concurrent requests are blocked.
     $checkModels = array("GO\\Calendar\\Model\\Event" => array('name', 'start_time', 'end_time', 'rrule', 'calendar_id'));
     foreach ($checkModels as $modelName => $checkFields) {
         if (empty($params['model']) || $modelName == $params['model']) {
             echo '<h1>' . \GO::t('removeDuplicates') . '</h1>';
             $checkFieldsStr = 't.' . implode(', t.', $checkFields);
             $findParams = \GO\Base\Db\FindParams::newInstance()->ignoreAcl()->select('t.id, count(*) AS n, ' . $checkFieldsStr)->group($checkFields)->having('n>1');
             $findParams->getCriteria()->addCondition('calendar_id', $calendar->id);
             $stmt1 = \GO::getModel($modelName)->find($findParams);
             echo '<table border="1">';
             echo '<tr><td>ID</th><th>' . implode('</th><th>', $checkFields) . '</th></tr>';
             $count = 0;
             while ($dupModel = $stmt1->fetch()) {
                 $select = 't.id';
                 if (\GO::getModel($modelName)->hasFiles()) {
                     $select .= ', t.files_folder_id';
                 }
                 $findParams = \GO\Base\Db\FindParams::newInstance()->ignoreAcl()->select($select . ', ' . $checkFieldsStr)->order('id', 'ASC');
                 $findParams->getCriteria()->addCondition('calendar_id', $calendar->id);
                 foreach ($checkFields as $field) {
                     $findParams->getCriteria()->addCondition($field, $dupModel->getAttribute($field));
                 }
                 $stmt = \GO::getModel($modelName)->find($findParams);
                 $first = true;
                 while ($model = $stmt->fetch()) {
                     echo '<tr><td>';
                     if (!$first) {
                         echo '<span style="color:red">';
                     }
                     echo $model->id;
                     if (!$first) {
                         echo '</span>';
                     }
                     echo '</th>';
                     foreach ($checkFields as $field) {
                         echo '<td>' . $model->getAttribute($field, 'html') . '</td>';
                     }
                     echo '</tr>';
                     if (!$first) {
                         if (!empty($params['delete'])) {
                             if ($model->hasLinks() && $model->countLinks()) {
                                 echo '<tr><td colspan="99">' . \GO::t('skippedDeleteHasLinks') . '</td></tr>';
                             } elseif (($filesFolder = $model->getFilesFolder(false)) && ($filesFolder->hasFileChildren() || $filesFolder->hasFolderChildren())) {
                                 echo '<tr><td colspan="99">' . \GO::t('skippedDeleteHasFiles') . '</td></tr>';
                             } else {
                                 $model->delete();
                             }
                         }
                         $count++;
                     }
                     $first = false;
                 }
             }
             echo '</table>';
             echo '<p>' . sprintf(\GO::t('foundDuplicates'), $count) . '</p>';
             echo '<br /><br /><a href="' . \GO::url('calendar/calendar/removeDuplicates', array('delete' => true, 'calendar_id' => $calendar->id)) . '">' . \GO::t('clickToDeleteDuplicates') . '</a>';
         }
     }
     $this->render('externalFooter');
 }