Пример #1
0
 /**
  * Authenticate to imap and return 
  * @return \GO\Base\Model\User 
  */
 public function imapAuthenticate()
 {
     //disable password validation because we can't control the external passwords
     \GO::config()->password_validate = false;
     $imap = new \GO\Base\Mail\Imap();
     try {
         $imap->connect($this->config['host'], $this->config['port'], $this->imapUsername, $this->imapPassword, $this->config['ssl']);
         \GO::debug('IMAPAUTH: IMAP login succesful');
         $imap->disconnect();
         $user = \GO\Base\Model\User::model()->findSingleByAttribute('username', $this->goUsername);
         if ($user) {
             \GO::debug("IMAPAUTH: Group-Office user already exists.");
             if (!$user->checkPassword($this->imapPassword)) {
                 \GO::debug('IMAPAUTH: IMAP password has been changed. Updating Group-Office database');
                 $user->password = $this->imapPassword;
                 if (!$user->save()) {
                     throw new \Exception("Could not save user: "******"\n", $user->getValidationErrors()));
                 }
             }
             $this->user = $user;
             if (\GO::modules()->isInstalled('email')) {
                 if (!$this->checkEmailAccounts($this->user, $this->config['host'], $this->imapUsername, $this->imapPassword)) {
                     $this->createEmailAccount($this->user, $this->config, $this->imapUsername, $this->imapPassword);
                 }
             }
         }
         return true;
     } catch (\Exception $e) {
         \GO::debug('IMAPAUTH: Authentication to IMAP server failed with Exception: ' . $e->getMessage() . ' IMAP error:' . $imap->last_error());
         $imap->clear_errors();
         \GO::session()->logout();
         //for clearing remembered password cookies
         return false;
     }
 }
Пример #2
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 CronJob $cronJob
  * @param \GO\Base\Model\User $user [OPTIONAL]
  */
 public function run(CronJob $cronJob, \GO\Base\Model\User $user = null)
 {
     \GO::session()->runAsRoot();
     $usersStmt = \GO\Base\Model\User::model()->findByAttribute('mail_reminders', 1);
     while ($userModel = $usersStmt->fetch()) {
         \GO::debug("Sending mail reminders to " . $userModel->username);
         $remindersStmt = \GO\Base\Model\Reminder::model()->find(\GO\Base\Db\FindParams::newInstance()->joinModel(array('model' => 'GO\\Base\\Model\\ReminderUser', 'localTableAlias' => 't', 'localField' => 'id', 'foreignField' => 'reminder_id', 'tableAlias' => 'ru'))->criteria(\GO\Base\Db\FindCriteria::newInstance()->addCondition('user_id', $userModel->id, '=', 'ru')->addCondition('time', time(), '<', 'ru')->addCondition('mail_sent', '0', '=', 'ru')));
         while ($reminderModel = $remindersStmt->fetch()) {
             //					$relatedModel = $reminderModel->getRelatedModel();
             //					var_dump($relatedModel->name);
             //					$modelName = $relatedModel ? $relatedModel->localizedName : \GO::t('unknown');
             $subject = \GO::t('reminder') . ': ' . $reminderModel->name;
             $time = !empty($reminderModel->vtime) ? $reminderModel->vtime : $reminderModel->time;
             date_default_timezone_set($userModel->timezone);
             $body = \GO::t('time') . ': ' . date($userModel->completeDateFormat . ' ' . $userModel->time_format, $time) . "\n";
             $body .= \GO::t('name') . ': ' . str_replace('<br />', ',', $reminderModel->name) . "\n";
             //					date_default_timezone_set(\GO::user()->timezone);
             $message = \GO\Base\Mail\Message::newInstance($subject, $body);
             $message->addFrom(\GO::config()->noreply_email, \GO::config()->title);
             $message->addTo($userModel->email, $userModel->name);
             \GO\Base\Mail\Mailer::newGoInstance()->send($message, $failedRecipients);
             if (!empty($failedRecipients)) {
                 trigger_error("Reminder mail failed for recipient: " . implode(',', $failedRecipients), E_USER_NOTICE);
             }
             $reminderUserModelSend = \GO\Base\Model\ReminderUser::model()->findSingleByAttributes(array('user_id' => $userModel->id, 'reminder_id' => $reminderModel->id));
             $reminderUserModelSend->mail_sent = 1;
             $reminderUserModelSend->save();
         }
         date_default_timezone_set(\GO::user()->timezone);
     }
 }
Пример #3
0
 /**
  * Set an authorization for an action so the current session is authorized to 
  * process the action.
  * 
  * @param string $name 
  */
 public static function setAuthorized($name)
 {
     if (empty(\GO::session()->values['Authorized'])) {
         \GO::session()->values['Authorized'] = array();
     }
     \GO::session()->values['Authorized'][] = $name;
 }
Пример #4
0
 protected function beforeSubmit(&$response, &$model, &$params)
 {
     if (!\GO::user()) {
         if (empty($params['serverclient_token']) || $params['serverclient_token'] != \GO::config()->serverclient_token) {
             throw new \GO\Base\Exception\AccessDenied();
         } else {
             \GO::session()->runAsRoot();
         }
     }
     if (isset($params['domain_id'])) {
         $domainModel = \GO\Postfixadmin\Model\Domain::model()->findByPk($params['domain_id']);
     } else {
         $domainModel = \GO\Postfixadmin\Model\Domain::model()->findSingleByAttribute("domain", $params['domain']);
         //serverclient module doesn't know the domain_id. It sends the domain name as string.
         if (!$domainModel) {
             //todo create new domain
             $domainModel = new \GO\Postfixadmin\Model\Domain();
             $domainModel->domain = $params['domain'];
             $domainModel->user_id = \GO::user()->id;
             $domainModel->save();
         }
         $params['domain_id'] = $domainModel->id;
         $model->quota = $domainModel->default_quota;
     }
     if (isset($params['quota'])) {
         $model->quota = \GO\Base\Util\Number::unlocalize($params['quota']) * 1024;
         unset($params['quota']);
     }
     if ($params['password'] != $params['password2']) {
         throw new \Exception(\GO::t('passwordMatchError'));
     }
     if (empty($params['password'])) {
         unset($params['password']);
     }
     if (isset($params['username'])) {
         $params['username'] .= '@' . $domainModel->domain;
     }
     if ($model->isNew) {
         //			$aliasModel = \GO\Postfixadmin\Model\Alias::model()->findSingleByAttribute('address', $params['username']);
         //			if (empty($aliasModel)) {
         //				$aliasModel = new \GO\Postfixadmin\Model\Alias();
         //			}
         //			$aliasModel->domain_id = $params['domain_id'];
         //			$aliasModel->address = $params['username'];
         //			$aliasModel->goto = $params['username'];
         //			$aliasModel->save();
         if (!empty($params['alias']) && $params['alias'] != $params['username']) {
             $aliasModel = \GO\Postfixadmin\Model\Alias::model()->findSingleByAttribute('address', $params['alias']);
             if (empty($aliasModel)) {
                 $aliasModel = new \GO\Postfixadmin\Model\Alias();
             }
             $aliasModel->domain_id = $params['domain_id'];
             $aliasModel->address = $params['alias'];
             $aliasModel->goto = $params['username'];
             $aliasModel->save();
         }
     }
 }
Пример #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();
     $pdf = $this->_getUserPdf($user);
     if ($this->_sendEmail($user, $pdf)) {
         \GO::debug("CRON MAIL IS SEND!");
     } else {
         \GO::debug("CRON MAIL HAS NOT BEEN SEND!");
     }
 }
 /**
  * Export the contact model to a .csv, including the company.
  * 
  * @param array $params
  */
 public function export($params)
 {
     GO::$disableModelCache = true;
     GO::setMaxExecutionTime(420);
     // Load the data from the session.
     $findParams = \GO::session()->values['contact']['findParams'];
     $findParams->getCriteria()->recreateTemporaryTables();
     $model = \GO::getModel(\GO::session()->values['contact']['model']);
     // Include the companies
     $findParams->joinRelation('company', 'LEFT');
     // Let the export handle all found records without a limit
     $findParams->limit(0);
     // Create the statement
     $stmt = $model->find($findParams);
     // Create the csv file
     $csvFile = new \GO\Base\Fs\CsvFile(\GO\Base\Fs\File::stripInvalidChars('export.csv'));
     // Output the download headers
     \GO\Base\Util\Http::outputDownloadHeaders($csvFile, false);
     $csvWriter = new \GO\Base\Csv\Writer('php://output');
     $headerPrinted = false;
     $attrs = array();
     $compAttrs = array();
     foreach ($stmt as $m) {
         $iterationStartUnix = time();
         if (!$headerPrinted) {
             $attrs = $m->getAttributes();
             $compAttrs = $m->company->getAttributes();
         }
         $header = array();
         $record = array();
         foreach ($attrs as $attr => $val) {
             if (!$headerPrinted) {
                 $header[$attr] = $m->getAttributeLabel($attr);
             }
             $record[$attr] = $m->{$attr};
         }
         foreach ($compAttrs as $cattr => $cval) {
             if (!$headerPrinted) {
                 $header[GO::t('company', 'addressbook') . $cattr] = GO::t('company', 'addressbook') . ':' . $m->company->getAttributeLabel($cattr);
             }
             $record[GO::t('company', 'addressbook') . $cattr] = $m->company->{$cattr};
         }
         if (!$headerPrinted) {
             $csvWriter->putRecord($header);
             $headerPrinted = true;
         }
         $csvWriter->putRecord($record);
     }
 }
 public function __construct($arguments)
 {
     if (isset($arguments['user'])) {
         $this->id = 'groupoffice::' . $arguments['user'] . '/';
         $this->groupoffice_data = \GO::config()->file_storage_path;
         \GO::session()->setCurrentUser(\GO\Base\Model\User::model()->findSingleByAttribute('username', $arguments['user']));
         $this->groupoffice_shares['ownFolder'] = 'users/' . $arguments['user'];
         $shares = \GO\Files\Model\Folder::model()->getTopLevelShares(\GO\Base\Db\FindParams::newInstance()->limit(100));
         foreach ($shares as $folder) {
             $this->groupoffice_shares[$folder->name] = $folder->path;
         }
     } else {
         throw new \Exception('Creating \\OC\\Files\\Storage\\Groupoffice storage failed');
     }
 }
Пример #8
0
 /**
  * The constructor for the exporter
  * 
  * @param \GO\Base\Data\Store $store
  * @param \GO\Base\Data\ColumnModel $columnModel
  * @param Boolean $header
  * @param Boolean $humanHeaders
  * @param String $title
  * @param Mixed $orientation ('P' for Portrait,'L' for Landscape of false for none) 
  */
 public function __construct(\GO\Base\Data\AbstractStore $store, $header = true, $humanHeaders = true, $title = false, $orientation = false)
 {
     $this->store = $store;
     $this->header = $header;
     $this->title = $title;
     $this->orientation = $orientation;
     $this->humanHeaders = $humanHeaders;
     if (is_a($store, "\\GO\\Base\\Data\\DbStore")) {
         $exportName = $this->store->getFindParams()->getParam('export');
         $this->totalizeColumns = isset(\GO::session()->values[$exportName]['totalizeColumns']) ? \GO::session()->values[$exportName]['totalizeColumns'] : array();
         foreach ($this->totalizeColumns as $column) {
             $this->totals[$column] = 0;
         }
     }
 }
Пример #9
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.");
 }
 public function checkPassword($uid, $password)
 {
     $this->_user[$uid] = \GO::session()->login($uid, $password, false);
     if (!$this->_user[$uid]) {
         return false;
     } else {
         //workaround bug in ownCloud
         $cache = \OC_User::getHome($uid) . '/cache';
         if (!is_dir($cache)) {
             mkdir($cache, 0755, true);
         }
         //make sure ownCloud folder exists in Group-Office
         $folder = new \GO\Base\Fs\Folder(\GO::config()->file_storage_path . 'users/' . $uid . $this->_groupoffice_mount);
         $folder->create();
         return $uid;
     }
 }
Пример #11
0
 protected function actionSwitch($params)
 {
     //
     //		if(!\GO::user()->isAdmin())
     //			throw new \Exception("This feature is for admins only!");
     $oldUsername = \GO::user()->username;
     $debug = !empty(\GO::session()->values['debug']);
     $user = \GO\Base\Model\User::model()->findByPk($params['user_id']);
     \GO::session()->values = array();
     //clear session
     \GO::session()->setCurrentUser($user->id);
     //\GO::session()->setCompatibilitySessionVars();
     if ($debug) {
         \GO::session()->values['debug'] = $debug;
     }
     \GO::infolog("ADMIN logged-in as user: \"" . $user->username . "\" from IP: " . $_SERVER['REMOTE_ADDR']);
     if (\GO::modules()->isInstalled('log')) {
         \GO\Log\Model\Log::create('switchuser', "'" . $oldUsername . "' logged in as '" . $user->username . "'");
     }
     $this->redirect();
 }
Пример #12
0
<?php 
$root = dirname(__FILE__) . '/';
//chdir($root);
//on the command line you can pass -c=/path/to/config.php to set the config file.
require_once $root . 'go/base/util/Cli.php';
$args = \GO\Base\Util\Cli::parseArgs();
if (isset($args['c'])) {
    define("GO_CONFIG_FILE", $args['c']);
}
//initialize autoloading of library
require_once $root . 'go/GO.php';
\GO::init();
if (!isset($args['q'])) {
    echo "\nGroup-Office CLI - Copyright Intermesh BV.\n\n";
}
if (PHP_SAPI != 'cli') {
    exit("ERROR: This script must be run on the command line\n\n");
}
if (empty($args['r'])) {
    echo "ERROR: You must pass a controller route to use the command line script.\n" . "eg.:\n\n" . "sudo -u www-data php index.php -c=/path/to/config.php -r=maintenance/upgrade --param=value\n\n";
    exit;
} elseif (isset($args['u'])) {
    $password = isset($args['p']) ? $args['p'] : \GO\Base\Util\Cli::passwordPrompt("Enter password for user " . $args['u'] . ":");
    $user = \GO::session()->login($args['u'], $password);
    if (!$user) {
        echo "Login failed for user " . $args['u'] . "\n";
        exit(1);
    }
    unset($args['u']);
}
\GO::router()->runController($args);
Пример #13
0
 /**
  * Calls buildSearchIndex on each Module class.
  * @return array 
  */
 protected function actionBuildSearchCache($params)
 {
     if (!$this->isCli() && !\GO::modules()->tools && \GO::router()->getControllerAction() != 'upgrade') {
         throw new \GO\Base\Exception\AccessDenied();
     }
     GO::setIgnoreAclPermissions(true);
     $this->lockAction();
     if (!$this->isCli()) {
         echo '<pre>';
     }
     \GO::session()->closeWriting();
     //close writing otherwise concurrent requests are blocked.
     $response = array();
     //		if(empty($params['keepexisting']))
     //			\GO::getDbConnection()->query('TRUNCATE TABLE go_search_cache');
     //
     //inserting is much faster without full text index. It's faster to add it again afterwards.
     //		echo "Dropping full text search index\n";
     //		try{
     //			\GO::getDbConnection()->query("ALTER TABLE go_search_cache DROP INDEX ft_keywords");
     //		}catch(\Exception $e){
     //			echo $e->getMessage()."\n";
     //		}
     if (!empty($params['modelName'])) {
         $modelName = $params['modelName'];
         if (empty($params['keepexisting'])) {
             $query = 'DELETE FROM go_search_cache WHERE model_name=' . \GO::getDbConnection()->quote($modelName);
             \GO::getDbConnection()->query($query);
         }
         $models = array(new ReflectionClass($modelName));
     } else {
         if (empty($params['keepexisting'])) {
             \GO::getDbConnection()->query('TRUNCATE TABLE go_search_cache');
         }
         $models = \GO::findClasses('model');
     }
     foreach ($models as $model) {
         if ($model->isSubclassOf("GO\\Base\\Db\\ActiveRecord") && !$model->isAbstract()) {
             echo "Processing " . $model->getName() . "\n";
             flush();
             $stmt = \GO::getModel($model->getName())->rebuildSearchCache();
         }
     }
     if (empty($params['modelName'])) {
         \GO::modules()->callModuleMethod('buildSearchCache', array(&$response));
     }
     //		echo "Adding full text search index\n";
     //		\GO::getDbConnection()->query("ALTER TABLE `go_search_cache` ADD FULLTEXT ft_keywords(`name` ,`keywords`);");
     echo "\n\nAll done!\n\n";
     if (!$this->isCli()) {
         echo '</pre>';
     }
 }
Пример #14
0
 /**
  * Page to show the ticketlist when a user is logged in
  */
 protected function actionTicketList()
 {
     if (!\GO::user()) {
         $this->redirect(array('tickets/site/ticketlogin'));
     }
     // Build the findparams to retreive the ticketlist from the DB
     $findParams = \GO\Base\Db\FindParams::newInstance();
     $findParams->getCriteria()->addCondition('user_id', \GO::user()->id);
     $findParams->order('mtime', 'DESC');
     if (!isset(\GO::session()->values['sites_ticketlist'])) {
         \GO::session()->values['sites_ticketlist'] = 'openprogress';
     }
     if (isset($_GET['filter'])) {
         \GO::session()->values['sites_ticketlist'] = $_GET['filter'];
     }
     // Option to filter the tickets
     switch (\GO::session()->values['sites_ticketlist']) {
         case 'open':
             $findParams->getCriteria()->addCondition('status_id', 0, '=');
             break;
         case 'progress':
             $findParams->getCriteria()->addCondition('status_id', 0, '>');
             break;
         case 'openprogress':
             $findParams->getCriteria()->addCondition('status_id', 0, '>=');
             break;
         case 'closed':
             $findParams->getCriteria()->addCondition('status_id', 0, '<');
             break;
         default:
             break;
     }
     // Create the pager for the ticket messages
     $pager = new \GO\Site\Widgets\Pager('p', $_REQUEST, \GO\Tickets\Model\Ticket::model(), $findParams, \GO::user()->max_rows_list, 2);
     // Render the ticketlist page
     $this->render('ticketlist', array('pager' => $pager));
 }
Пример #15
0
 /**
  * Sets current user for the entire session. Use it wisely!
  * @param int/Model\User $user_id
  */
 public function setCurrentUser($user_id)
 {
     //		if(\GO::modules()->isInstalled("log"))
     //			\GO\Log\Model\Log::create ("setcurrentuser", "Set user ID to $user_id");
     if ($user_id instanceof Model\User) {
         $this->_user = $user_id;
         $this->values['user_id'] = $user_id->id;
     } else {
         //remember user id in session
         $this->values['user_id'] = $user_id;
     }
     if (!\GO::user()) {
         throw new \Exception("Could not set user with id " . $user_id . " in Session::setCurrentUser()!");
     }
     date_default_timezone_set(\GO::user()->timezone);
     \GO::language()->setLanguage(\GO::user()->language);
     //for logging
     \GO::session()->values['username'] = \GO::user()->username;
 }
Пример #16
0
 protected function actionBatchSend($params)
 {
     $this->requireCli();
     $this->_sentEmails = array();
     \GO::$disableModelCache = true;
     $mailing = \GO\Addressbook\Model\SentMailing::model()->findByPk($params['mailing_id']);
     if (!$mailing) {
         throw new \Exception("Mailing not found!\n");
     }
     \GO::session()->runAs($mailing->user_id);
     echo 'Status: ' . $mailing->status . "\n";
     if (empty($mailing->status)) {
         echo "Starting mailing at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
         $mailing->reset();
     } elseif (!empty($params['restart'])) {
         echo "Restarting mailing at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
         $mailing->reset();
     } elseif ($mailing->status == \GO\Addressbook\Model\SentMailing::STATUS_PAUSED) {
         echo "Resuming mailing at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
         $mailing->status = \GO\Addressbook\Model\SentMailing::STATUS_RUNNING;
         $mailing->save();
     }
     $htmlToText = new \GO\Base\Util\Html2Text();
     //$addresslist = \GO\Addressbook\Model\Addresslist::model()->findByPk($mailing->addresslist_id);
     $mimeData = file_get_contents(\GO::config()->file_storage_path . $mailing->message_path);
     $message = \GO\Base\Mail\Message::newInstance()->loadMimeMessage($mimeData);
     $joinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addRawCondition('t.id', 'a.account_id');
     $findParams = \GO\Base\Db\FindParams::newInstance()->single()->join(\GO\Email\Model\Alias::model()->tableName(), $joinCriteria, 'a')->criteria(\GO\Base\Db\FindCriteria::newInstance()->addCondition('id', $mailing->alias_id, '=', 'a'));
     if ($mailing->campaign_id > 0 && \GO::modules()->isAvailable('campaigns')) {
         $account = new \GO\Email\Model\Account();
         $account->username = \GO::config()->campaigns_imap_user;
         $account->password = \GO::config()->campaigns_imap_pass;
         $account->host = \GO::config()->campaigns_imap_server;
         $account->port = \GO::config()->campaigns_imap_port;
         $account->smtp_username = \GO::config()->campaigns_smtp_user;
         $account->smtp_password = \GO::config()->campaigns_smtp_pass;
         $account->smtp_host = \GO::config()->campaigns_smtp_server;
         $account->smtp_port = \GO::config()->campaigns_smtp_port;
         $message->setFrom(\GO::config()->campaigns_from);
     } else {
         $account = \GO\Email\Model\Account::model()->find($findParams);
         if (!$account->store_password && !empty($mailing->temp_pass)) {
             $account->smtp_password = $mailing->temp_pass;
         }
     }
     $mailer = \GO\Base\Mail\Mailer::newGoInstance(\GO\Email\Transport::newGoInstance($account));
     echo "Will send emails from " . $account->username . ".\n";
     if (empty(\GO::config()->mailing_messages_per_minute)) {
         \GO::config()->mailing_messages_per_minute = 30;
     }
     //Rate limit to 100 emails per-minute
     $mailer->registerPlugin(new \Swift_Plugins_ThrottlerPlugin(\GO::config()->mailing_messages_per_minute, \Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE));
     // Use AntiFlood to re-connect after 50 emails
     $mailer->registerPlugin(new \Swift_Plugins_AntiFloodPlugin(\GO::config()->mailing_messages_per_minute));
     echo 'Sending a maximum of ' . \GO::config()->mailing_messages_per_minute . ' messages per minute' . "\n";
     $failedRecipients = array();
     $bodyWithTags = $message->getBody();
     foreach ($mailing->contacts as $contact) {
         $sentMailingContactModel = \GO\Addressbook\Model\SentMailingContact::model()->findSingleByAttributes(array('sent_mailing_id' => $mailing->id, 'contact_id' => $contact->id));
         if (!$sentMailingContactModel->sent) {
             $errors = 1;
             $unsubscribeHref = \GO::url('addressbook/sentMailing/unsubscribe', array('addresslist_id' => $mailing->addresslist_id, 'contact_id' => $contact->id, 'token' => md5($contact->ctime . $contact->addressbook_id . $contact->firstEmail)), false, true);
             $body = str_replace('%unsubscribe_href%', $unsubscribeHref, $bodyWithTags);
             //curly brackets don't work inside links in browser wysiwyg editors.
             $templateModel = \GO\Addressbook\Model\Template::model();
             $templateModel->htmlSpecialChars = false;
             $body = $templateModel->replaceCustomTags($body, array('unsubscribe_link' => '<a href="' . $unsubscribeHref . '" target="_blank">' . \GO::t("unsubscription", "addressbook") . '</a>'), true);
             $templateModel->htmlSpecialChars = true;
             try {
                 if (!$contact->email_allowed) {
                     echo "Skipping contact " . $contact->firstEmail . " because newsletter sending is disabled in the addresslists tab.\n\n";
                 } elseif (empty($contact->firstEmail)) {
                     echo "Skipping contact " . $contact->name . " no e-mail address was set.\n\n";
                 } else {
                     $body = \GO\Addressbook\Model\Template::model()->replaceContactTags($body, $contact);
                     $message->setTo($contact->firstEmail, $contact->name);
                     $message->setBody($body);
                     $plainTextPart = $message->findPlainTextBody();
                     if ($plainTextPart) {
                         $htmlToText->set_html($body);
                         $plainTextPart->setBody($htmlToText->get_text());
                     }
                     // Check mail limit
                     $nSentMails = \GO::config()->get_setting('campaigns_number_sent_mails', 0);
                     if ($mailing->campaign_id > 0 && $nSentMails >= \GO::config()->campaigns_max_mails_per_period) {
                         $this->_pauseMailing($mailing->id);
                         echo "Error for " . $contact->firstEmail . ": \n";
                         echo str_replace('%maxMails', \GO::config()->campaigns_max_mails_per_period, \GO::t('sentMailLimitReached', 'campaigns'));
                         exit;
                     }
                     $this->_sendmail($message, $contact, $mailer, $mailing);
                     \GO::config()->save_setting('campaigns_number_sent_mails', $nSentMails + 1, 0);
                     $errors = 0;
                 }
             } catch (\Exception $e) {
                 echo "Error for " . $contact->firstEmail . ": " . $e->getMessage() . "\n";
             }
             if ($errors) {
                 $mailing->errors++;
                 $mailing->save();
             }
         }
     }
     foreach ($mailing->companies as $company) {
         $sentMailingCompanyModel = \GO\Addressbook\Model\SentMailingCompany::model()->findSingleByAttributes(array('sent_mailing_id' => $mailing->id, 'company_id' => $company->id));
         if (!$sentMailingCompanyModel->sent) {
             $errors = 1;
             $unsubscribeHref = \GO::url('addressbook/sentMailing/unsubscribe', array('addresslist_id' => $mailing->addresslist_id, 'company_id' => $company->id, 'token' => md5($company->ctime . $company->addressbook_id . $company->email)), true, true);
             $body = str_replace('%unsubscribe_href%', $unsubscribeHref, $bodyWithTags);
             //curly brackets don't work inside links in browser wysiwyg editors.
             $body = \GO\Addressbook\Model\Template::model()->replaceCustomTags($body, array('unsubscribe_link' => '<a href="' . $unsubscribeHref . '">' . \GO::t("unsubscription", "addressbook") . '</a>'), true);
             try {
                 if (!$company->email_allowed) {
                     echo "Skipping company " . $company->email . " because newsletter sending is disabled in the addresslists tab.\n\n";
                 } elseif (empty($company->email)) {
                     echo "Skipping company " . $company->name . " no e-mail address was set.\n\n";
                 } else {
                     $body = \GO\Addressbook\Model\Template::model()->replaceModelTags($body, $company);
                     $message->setTo($company->email, $company->name);
                     $message->setBody($body);
                     $plainTextPart = $message->findPlainTextBody();
                     if ($plainTextPart) {
                         $htmlToText->set_html($body);
                         $plainTextPart->setBody($htmlToText->get_text());
                     }
                     // Check mail limit
                     $nSentMails = \GO::config()->get_setting('campaigns_number_sent_mails', 0);
                     if ($mailing->campaign_id > 0 && $nSentMails >= \GO::config()->campaigns_max_mails_per_period) {
                         $this->_pauseMailing($mailing->id);
                         echo "Error for " . $contact->firstEmail . ": \n";
                         echo str_replace('%maxMails', \GO::config()->campaigns_max_mails_per_period, \GO::t('sentMailLimitReached', 'campaigns'));
                         exit;
                     }
                     $this->_sendmail($message, $company, $mailer, $mailing);
                     \GO::config()->save_setting('campaigns_number_sent_mails', $nSentMails + 1, 0);
                     $errors = 0;
                 }
             } catch (\Exception $e) {
                 echo "Error for " . $company->email . ": " . $e->getMessage() . "\n";
             }
             if ($errors) {
                 $mailing->errors++;
                 $mailing->save();
             }
         }
     }
     $mailing->status = \GO\Addressbook\Model\SentMailing::STATUS_FINISHED;
     // Unset the temp_pass
     if (!empty($mailing->temp_pass)) {
         $mailing->temp_pass = "";
     }
     $mailing->save();
     echo "Mailing finished at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
 }
Пример #17
0
 private function _setSelectedIds(array $requestParams)
 {
     if (isset($requestParams[$this->_requestParamName])) {
         $this->selectedIds = json_decode($requestParams[$this->_requestParamName], true);
         $this->_save();
     } else {
         $selectedPks = \GO::config()->get_setting('ms_' . $this->_requestParamName, \GO::session()->values['user_id']);
         $this->selectedIds = empty($selectedPks) && $selectedPks !== '0' ? array() : explode(',', $selectedPks);
     }
     //add all the allowed models if it's empty. It's faster to find all allowed
     //addressbooks then too join the acl table.
     //That's why this component add's ignoreAcl() to the findParams automatically
     //in the addSelectedToFindCriteria() function. The permissions are checked by
     //the following query.
     if ($this->_checkPermissions && empty($this->selectedIds)) {
         $stmt = \GO::getModel($this->_modelName)->find();
         foreach ($stmt as $model) {
             $this->selectedIds[] = $model->pk;
         }
         $this->_save();
     }
 }
Пример #18
0
 public static function handleUpload()
 {
     $tmpFolder = new \GO\Base\Fs\Folder(\GO::config()->tmpdir . 'uploadqueue');
     //$tmpFolder->delete();
     $tmpFolder->create();
     //		$files = \GO\Base\Fs\File::moveUploadedFiles($_FILES['attachments'], $tmpFolder);
     //		\GO::session()->values['files']['uploadqueue'] = array();
     //		foreach ($files as $file) {
     //			\GO::session()->values['files']['uploadqueue'][] = $file->path();
     //		}
     if (!isset(\GO::session()->values['files']['uploadqueue'])) {
         \GO::session()->values['files']['uploadqueue'] = array();
     }
     $targetDir = $tmpFolder->path();
     // Get parameters
     $chunk = isset($_POST["chunk"]) ? $_POST["chunk"] : 0;
     $chunks = isset($_POST["chunks"]) ? $_POST["chunks"] : 0;
     $fileName = isset($_POST["name"]) ? $_POST["name"] : '';
     // Clean the fileName for security reasons
     $fileName = \GO\Base\Fs\File::stripInvalidChars($fileName);
     // Make sure the fileName is unique but only if chunking is disabled
     //		if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
     //			$ext = strrpos($fileName, '.');
     //			$fileName_a = substr($fileName, 0, $ext);
     //			$fileName_b = substr($fileName, $ext);
     //
     //			$count = 1;
     //			while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
     //				$count++;
     //
     //			$fileName = $fileName_a . '_' . $count . $fileName_b;
     //		}
     // Look for the content type header
     if (isset($_SERVER["HTTP_CONTENT_TYPE"])) {
         $contentType = $_SERVER["HTTP_CONTENT_TYPE"];
     }
     if (isset($_SERVER["CONTENT_TYPE"])) {
         $contentType = $_SERVER["CONTENT_TYPE"];
     }
     if (!in_array($targetDir . DIRECTORY_SEPARATOR . $fileName, \GO::session()->values['files']['uploadqueue'])) {
         \GO::session()->values['files']['uploadqueue'][] = $targetDir . DIRECTORY_SEPARATOR . $fileName;
     }
     $file = new \GO\Base\Fs\File($targetDir . DIRECTORY_SEPARATOR . $fileName);
     if ($file->exists() && $file->size() > \GO::config()->max_file_size) {
         throw new \Exception("File too large");
     }
     // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
     if (strpos($contentType, "multipart") !== false) {
         if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
             // Open temp file
             $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
             if ($out) {
                 // Read binary input stream and append it to temp file
                 $in = fopen($_FILES['file']['tmp_name'], "rb");
                 if ($in) {
                     while ($buff = fread($in, 4096)) {
                         fwrite($out, $buff);
                     }
                 } else {
                     die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
                 }
                 fclose($in);
                 fclose($out);
                 @unlink($_FILES['file']['tmp_name']);
             } else {
                 die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
             }
         } else {
             die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
         }
     } else {
         // Open temp file
         $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
         if ($out) {
             // Read binary input stream and append it to temp file
             $in = fopen("php://input", "rb");
             if ($in) {
                 while ($buff = fread($in, 4096)) {
                     fwrite($out, $buff);
                 }
             } else {
                 die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
             }
             fclose($in);
             fclose($out);
         } else {
             die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
         }
     }
     // Return JSON-RPC response
     die('{"jsonrpc" : "2.0", "result": null, "success":true, "id" : "id"}');
 }
Пример #19
0
 /**
  * add a new note to the session
  * @param string $key the key of the message
  * @param string $value the message
  */
 public function setMessage($key, $value)
 {
     \GO::session()->values['notifier'][$key] = $value;
 }
Пример #20
0
 public function decryptSmtpPassword()
 {
     if (!empty(\GO::session()->values['emailModule']['smtpPasswords'][$this->id])) {
         $decrypted = \GO\Base\Util\Crypt::decrypt(\GO::session()->values['emailModule']['smtpPasswords'][$this->id]);
     } else {
         //support for z-push without storing passwords
         if (empty($this->smtp_password) && method_exists('Request', 'GetAuthPassword') && Request::GetAuthUser() == $this->smtp_username) {
             $decrypted = Request::GetAuthPassword();
         } else {
             $decrypted = \GO\Base\Util\Crypt::decrypt($this->smtp_password);
         }
     }
     return $decrypted ? $decrypted : $this->smtp_password;
 }
Пример #21
0
    public function actionTestVObject($params)
    {
        \GO::session()->runAsRoot();
        $ical_str = 'BEGIN:VCALENDAR
VERSION:1.0
BEGIN:VEVENT
UID:762
SUMMARY:weekly test
DTSTART:20040503T160000Z
DTEND:20040503T170000Z
X-EPOCAGENDAENTRYTYPE:APPOINTMENT
CLASS:PUBLIC
DCREATED:20040502T220000Z
RRULE:W1 MO #0
LAST-MODIFIED:20040503T101900Z
PRIORITY:0
STATUS:NEEDS ACTION
END:VEVENT
END:VCALENDAR';
        $vobject = \GO\Base\VObject\Reader::read($ical_str);
        $event = new \GO\Calendar\Model\Event();
        $event->importVObject($vobject->vevent[0]);
        var_dump($event->getAttributes());
    }
Пример #22
0
 protected function actionCompanies($params)
 {
     $store = \GO\Base\Data\Store::newInstance(\GO\Addressbook\Model\Company::model());
     $store->getColumnModel()->formatColumn('name', '$model->name', array(), array('first_name', 'last_name'));
     $store->getColumnModel()->formatColumn('addressbook_name', '$model->addressbook->name', array(), 'addressbook_id');
     $store->processDeleteActions($params, "GO\\Addressbook\\Model\\AddresslistCompany", array('addresslist_id' => $params['addresslist_id']));
     $response = array();
     if (!empty($params['add_addressbook_id'])) {
         $addressbook = \GO\Addressbook\Model\Addressbook::model()->findByPk($params['add_addressbook_id']);
         $model = \GO\Addressbook\Model\Addresslist::model()->findByPk($params['addresslist_id']);
         $stmt = $addressbook->companies();
         while ($company = $stmt->fetch()) {
             $model->addManyMany('companies', $company->id);
         }
     } elseif (!empty($params['add_keys'])) {
         $add_keys = json_decode($params['add_keys'], true);
         $model = !isset($model) ? \GO\Addressbook\Model\Addresslist::model()->findByPk($params['addresslist_id']) : $model;
         foreach ($add_keys as $add_key) {
             $model->addManyMany('companies', $add_key);
         }
     } elseif (!empty($params['add_search_result'])) {
         $findParams = \GO::session()->values["company"]['findParams'];
         $findParams->getCriteria()->recreateTemporaryTables();
         $findParams->limit(0)->select('t.id');
         $model = \GO\Addressbook\Model\Addresslist::model()->findByPk($params['addresslist_id']);
         $stmt = \GO\Addressbook\Model\Company::model()->find($findParams);
         foreach ($stmt as $contact) {
             $model->addManyMany('companies', $contact->id);
         }
     }
     $stmt = \GO\Addressbook\Model\Addresslist::model()->findByPk($params['addresslist_id'])->companies($store->getDefaultParams($params));
     $store->setDefaultSortOrder('name', 'ASC');
     $store->setStatement($stmt);
     return array_merge($response, $store->getData());
 }
Пример #23
0
 /**
  * joining on the addressbooks can be very expensive. That's why this 
  * session cached useful can be used to optimize addressbook queries.
  * 
  * @return array
  */
 public function getAllReadableAddressbookIds()
 {
     if (!isset(\GO::session()->values['addressbook']['readable_addressbook_ids'])) {
         \GO::session()->values['addressbook']['readable_addressbook_ids'] = array();
         $stmt = $this->find();
         while ($ab = $stmt->fetch()) {
             \GO::session()->values['addressbook']['readable_addressbook_ids'][] = $ab->id;
         }
     }
     return \GO::session()->values['addressbook']['readable_addressbook_ids'];
 }
Пример #24
0
 /**
  * Logout the current user and redirect to loginpage 
  */
 public function actionLogout()
 {
     \GO::session()->logout();
     \GO::session()->start();
     $this->redirect(\Site::urlManager()->getHomeUrl());
 }
Пример #25
0
 /**
  * Sends a meeting request to all participants. If the participant is not a Group-Office user
  * or the organizer has no permissions to schedule an event it will include an
  * icalendar attachment so the calendar software can schedule it.
  * 
  * @return boolean
  * @throws Exception
  */
 public function sendMeetingRequest($newParticipantsOnly = false, $update = false)
 {
     if (!$this->is_organizer) {
         throw new \Exception("Meeting request can only be send from the organizer's event");
     }
     $stmt = $this->participants;
     //handle missing user
     if (!$this->user) {
         $this->user_id = 1;
         $this->save(true);
     }
     while ($participant = $stmt->fetch()) {
         if (!$newParticipantsOnly || isset(\GO::session()->values['new_participant_ids']) && in_array($participant->user_id, \GO::session()->values['new_participant_ids'])) {
             //don't invite organizer
             if ($participant->is_organizer) {
                 continue;
             }
             // Set the language of the email to the language of the participant.
             $language = false;
             if (!empty($participant->user_id)) {
                 $user = \GO\Base\Model\User::model()->findByPk($participant->user_id);
                 if ($user) {
                     \GO::language()->setLanguage($user->language);
                 }
             }
             //if participant status is pending then send a new inviation subject. Otherwise send it as update
             if (!$update) {
                 $subject = \GO::t('invitation', 'calendar') . ': ' . $this->name;
                 $bodyLine = \GO::t('invited', 'calendar');
             } else {
                 $subject = \GO::t('invitation_update', 'calendar') . ': ' . $this->name;
                 $bodyLine = \GO::t('eventUpdated', 'calendar');
             }
             //create e-mail message
             $message = \GO\Base\Mail\Message::newInstance($subject)->setFrom($this->user->email, $this->user->name)->addTo($participant->email, $participant->name);
             //check if we have a Group-Office event. If so, we can handle accepting
             //and declining in Group-Office. Otherwise we'll use ICS calendar objects by mail
             $participantEvent = $participant->getParticipantEvent();
             $body = '<p>' . $bodyLine . ': </p>' . $this->toHtml();
             //				if(!$participantEvent){
             //build message for external program
             $acceptUrl = \GO::url("calendar/event/invitation", array("id" => $this->id, 'accept' => 1, 'email' => $participant->email, 'participantToken' => $participant->getSecurityToken()), false);
             $declineUrl = \GO::url("calendar/event/invitation", array("id" => $this->id, 'accept' => 0, 'email' => $participant->email, 'participantToken' => $participant->getSecurityToken()), false);
             //				if($participantEvent){
             //hide confusing buttons if user has a GO event.
             $body .= '<div class="go-hidden">';
             //				}
             $body .= '<p><br /><b>' . \GO::t('linkIfCalendarNotSupported', 'calendar') . '</b></p>' . '<p>' . \GO::t('acccept_question', 'calendar') . '</p>' . '<a href="' . $acceptUrl . '">' . \GO::t('accept', 'calendar') . '</a>' . '&nbsp;|&nbsp;' . '<a href="' . $declineUrl . '">' . \GO::t('decline', 'calendar') . '</a>';
             //				if($participantEvent){
             $body .= '</div>';
             //				}
             $ics = $this->toICS("REQUEST");
             $a = \Swift_Attachment::newInstance($ics, \GO\Base\Fs\File::stripInvalidChars($this->name) . '.ics', 'text/calendar; METHOD="REQUEST"');
             $a->setEncoder(new Swift_Mime_ContentEncoder_PlainContentEncoder("8bit"));
             $a->setDisposition("inline");
             $message->attach($a);
             //for outlook 2003 compatibility
             $a2 = \Swift_Attachment::newInstance($ics, 'invite.ics', 'application/ics');
             $a2->setEncoder(new Swift_Mime_ContentEncoder_PlainContentEncoder("8bit"));
             $message->attach($a2);
             if ($participantEvent) {
                 $url = \GO::createExternalUrl('calendar', 'openCalendar', array('unixtime' => $this->start_time));
                 $body .= '<br /><a href="' . $url . '">' . \GO::t('openCalendar', 'calendar') . '</a>';
             }
             $message->setHtmlAlternateBody($body);
             // Set back the original language
             if ($language !== false) {
                 \GO::language()->setLanguage($language);
             }
             \GO\Base\Mail\Mailer::newGoInstance()->send($message);
         }
     }
     unset(\GO::session()->values['new_participant_ids']);
     return true;
 }
Пример #26
0
 protected function actionStore($params)
 {
     \GO::session()->closeWriting();
     $response = array("results" => array(), "success" => true);
     $account = \GO\Email\Model\Account::model()->findByPk($params['account_id']);
     $mailboxes = $account->getAllMailboxes(false, false);
     foreach ($mailboxes as $mailbox) {
         $response['results'][] = array('name' => $mailbox->name, 'account_id' => $params['account_id']);
     }
     $response['trash'] = $account->trash;
     return $response;
 }
Пример #27
0
 function send_command($command, $piped = false)
 {
     if ($piped) {
         $final_command = '';
         foreach ($command as $v) {
             $final_command .= 'A' . $this->command_number() . ' ' . $v;
         }
         $command = $final_command;
     } else {
         $command = 'A' . $this->command_number() . ' ' . $command;
     }
     if (!is_resource($this->handle)) {
         throw new \Exception("Lost connection to " . $this->server);
     }
     $this->lastCommand = $command;
     if (!fputs($this->handle, $command)) {
         throw new \Exception("Lost connection to " . $this->server);
         //				eturn false;
     }
     if (!empty(\GO::session()->values['debugSql'])) {
         \GO::debug("S: " . $command);
     }
     $this->commands[trim($command)] = \GO\Base\Util\Date::getmicrotime();
 }
Пример #28
0
 protected function actionEditinglist()
 {
     $empty_editing = true;
     if ($list = \GO::session()->values['googledrive']['editing']) {
         if (!count(\GO::session()->values['googledrive']['editing']) < 1) {
             $empty_editing = false;
         }
     }
     if (!$empty_editing) {
         $list = \GO::session()->values['googledrive']['editing'];
         $response['success'] = true;
         $response['values'] = [];
         $response['names'] = [];
         foreach ($list as $k => $v) {
             $goFile = \GO\Files\Model\File::model()->findByPk($k);
             array_push($response['values'], $k);
             array_push($response['names'], $goFile->name);
         }
     } else {
         throw new Exception("No hay archivos abiertos");
         $response['success'] = false;
     }
     return $response;
 }
Пример #29
0
 protected function actionDownload($params)
 {
     \GO::session()->closeWriting();
     \GO::setMaxExecutionTime(0);
     if (isset($params['path'])) {
         $folder = \GO\Files\Model\Folder::model()->findByPath(dirname($params['path']));
         $file = $folder->hasFile(\GO\Base\Fs\File::utf8Basename($params['path']));
     } else {
         $file = \GO\Files\Model\File::model()->findByPk($params['id'], false, true);
     }
     if (!$file) {
         throw new \GO\Base\Exception\NotFound();
     }
     if (!empty($params['random_code'])) {
         if ($file->random_code != $params['random_code']) {
             throw new \GO\Base\Exception\NotFound();
         }
         if (time() > $file->expire_time) {
             throw new \Exception(\GO::t('downloadLinkExpired', 'files'));
         }
     } else {
         $public = substr($file->path, 0, 6) == 'public';
         if (!$public) {
             if (!\GO::user()) {
                 \GO\Base\Util\Http::basicAuth();
             }
             if (!$file->checkPermissionLevel(\GO\Base\Model\Acl::READ_PERMISSION)) {
                 throw new \GO\Base\Exception\AccessDenied();
             }
         }
     }
     // Show the file inside the browser or give it as a download
     $inline = true;
     // Defaults to show inside the browser
     if (isset($params['inline']) && $params['inline'] == "false") {
         $inline = false;
     }
     \GO\Base\Util\Http::outputDownloadHeaders($file->fsFile, $inline, !empty($params['cache']));
     $file->open();
     $this->fireEvent('beforedownload', array(&$this, &$params, &$file));
     $file->fsFile->output();
 }
Пример #30
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();
        }
    }