/** * メール送信 * * @return void */ public function send() { // SiteSettingからメール設定を取得する SiteSettingUtil::setup(array('Mail.from', 'Mail.from_name', 'Mail.messageType', 'Mail.transport', 'Mail.smtp.host', 'Mail.smtp.port', 'Mail.smtp.user', 'Mail.smtp.pass', 'App.site_name')); $from = SiteSettingUtil::read('Mail.from'); // Fromが空ならメール未設定のため、メール送らない if (empty($from)) { $this->out('<error>From Address is empty. [' . __METHOD__ . ']</error>'); return $this->_stop(); } $now = NetCommonsTime::getNowDatetime(); // キュー取得&ロック - シェル実行の排他を実現したいため、行ロックしている // http://k-1blog.com/development/program/post-7407/ // http://d.hatena.ne.jp/fat47/20140212/1392171784 // 下記SQL(テーブル結合&範囲条件)でSELECT FOR UPDATEを実行すると、テーブルロック $sql = 'SELECT * FROM ' . 'mail_queues MailQueue, ' . 'mail_queue_users MailQueueUser ' . 'WHERE ' . 'MailQueue.id = MailQueueUser.mail_queue_id ' . 'AND MailQueue.send_time <= ? ' . 'FOR UPDATE '; $mailQueues = $this->MailQueue->query($sql, array($now)); if (empty($mailQueues)) { $this->out('MailQueue is empty. [' . __METHOD__ . '] '); return $this->_stop(); } $beforeId = $mailQueues[0]['MailQueue']['id']; $isSend = null; foreach ($mailQueues as $mailQueue) { // idが変わったら、MailQueue削除 if ($beforeId != $mailQueue['MailQueue']['id']) { $this->MailQueue->delete($beforeId); $isSend = null; } // ブロック非公開、期間限定の対応 if (is_null($isSend)) { $isSend = $this->_isSendBlockType($mailQueue); } if ($isSend) { $mail = new NetCommonsMail(); $mail->initShell($mailQueue); try { $mail->sendQueueMail($mailQueue['MailQueueUser'], $mailQueue['MailQueue']['language_id']); } catch (Exception $ex) { // SMTPの設定間違い等で送れなくても、処理を続行。メールは破棄(設定間違いでメールがキューに溜まる事を防ぐ) CakeLog::error($ex); } } // MailQueueUser削除 $this->MailQueueUser->delete($mailQueue['MailQueueUser']['id']); $beforeId = $mailQueue['MailQueue']['id']; } // 後始末 - MailQueue削除 $this->MailQueue->delete($beforeId); }
/** * メール送信日時で送るかどうか * * @param date $sendTime メール送信日時 * @param int $useReminder リマインダーを使うか * @return bool */ public function isMailSendTime($sendTime, $useReminder) { if ($sendTime === null) { return true; } // SiteSettingからメール設定を取得する $useCron = SiteSettingUtil::read('Mail.use_cron'); $now = NetCommonsTime::getNowDatetime(); // クーロンが使えなくて未来日なら、未来日メールなので送らない if (empty($useCron) && strtotime($now) < strtotime($sendTime)) { return false; } //$useReminder = $this->settings[$model->alias]['reminder']['useReminder']; if (!$useReminder) { return true; } // リマインダーで日時が過ぎてたら、メール送らない if (strtotime($now) > strtotime($sendTime)) { return false; } return true; }
/** * ルーム配信で送らないユーザID ゲット * * @param string $sendTime メール送信日時 * @param array $notSendRoomUserIds ルーム配信で送らないユーザID * @return string ルーム配信で送らないユーザID */ private function __getNotSendRoomUserIds($sendTime, $notSendRoomUserIds) { // 未来日送信は2通(承認完了とルーム配信)送るため、送らないユーザIDをセットしない $now = NetCommonsTime::getNowDatetime(); if ($sendTime > $now) { return null; } // 重複登録を排除 $notSendRoomUserIds = array_unique($notSendRoomUserIds); // 空要素を排除 $notSendRoomUserIds = Hash::filter($notSendRoomUserIds); $notSendRoomUserIds = implode('|', $notSendRoomUserIds); return $notSendRoomUserIds; }
/** * 初期設定 タグ * * @param int $languageId 言語ID * @param string $pluginName プラグイン名 * @return void */ public function initTags($languageId, $pluginName = null) { if ($pluginName === null) { $pluginName = Current::read('Plugin.name'); } $from = SiteSettingUtil::read('Mail.from'); $fromName = SiteSettingUtil::read('Mail.from_name', null, $languageId); $siteName = SiteSettingUtil::read('App.site_name', null, $languageId); $bodyHeader = SiteSettingUtil::read('Mail.body_header', null, $languageId); $signature = SiteSettingUtil::read('Mail.signature', null, $languageId); $siteTimezone = (new NetCommonsTime())->getSiteTimezone(); $now = NetCommonsTime::getNowDatetime(); $date = new DateTime($now); $date->setTimezone(new DateTimeZone($siteTimezone)); $siteNow = $date->format('Y/m/d H:i:s'); $this->assignTag('X-FROM_EMAIL', $from); $this->assignTag('X-FROM_NAME', $fromName); $this->assignTag('X-SITE_NAME', $siteName); $this->assignTag('X-SITE_URL', Router::fullbaseUrl()); $this->assignTag('X-PLUGIN_NAME', $pluginName); $this->assignTag('X-BLOCK_NAME', Current::read('Block.name')); $this->assignTag('X-TO_DATE', $siteNow); $this->assignTag('X-BODY_HEADER', $bodyHeader); $this->assignTag('X-SIGNATURE', $signature); // X-ROOMタグ $this->setXRoom($languageId); }
/** * 時限公開のconditionsを返す * * @param Model $model 対象モデル * @return array */ protected function _getPublicTypeConditions(Model $model) { $netCommonsTime = new NetCommonsTime(); $limitedConditions = array(); $limitedConditions[$model->alias . '.public_type'] = self::PUBLIC_TYPE_LIMITED; if ($model->hasField('publish_start')) { $limitedConditions[] = array('OR' => array($model->alias . '.publish_start <=' => $netCommonsTime->getNowDatetime(), $model->alias . '.publish_start' => null)); } if ($model->hasField('publish_end')) { $limitedConditions[] = array('OR' => array($model->alias . '.publish_end >=' => $netCommonsTime->getNowDatetime(), $model->alias . '.publish_end' => null)); } $publicTypeConditions = array('OR' => array($model->alias . '.public_type' => self::PUBLIC_TYPE_PUBLIC, $limitedConditions)); return $publicTypeConditions; }
/** * リマインダー送信日時 セット * * #### サンプルコード * ##### Model * ```php * public function saveVideo($data) { * $this->begin(); * * $this->set($data); * if (! $this->validates()) { * return false; * } * * try { * // 試し:リマインダー(カレンダー等) * // 送信条件:site_settings['Mail.use_cron'] => 1 * $netCommonsTime = new NetCommonsTime(); * $sendTimes = array( * $netCommonsTime->toServerDatetime('2017-03-31 14:30:00'), * $netCommonsTime->toServerDatetime('2017-04-20 13:30:00'), * ); * $this->setSendTimeReminder($sendTimes); * * if (! $video = $this->save(null, false)) { * throw new InternalErrorException(__d('net_commons', 'Internal Server Error')); * } * $this->commit(); * * } catch (Exception $ex) { * $this->rollback($ex); * } * return $video; * } * ``` * * @param Model $model モデル * @param array $sendTimeReminders リマインダー送信日時 配列 * @return array $this->settings(テスト用) */ public function setSendTimeReminder(Model $model, $sendTimeReminders) { $now = NetCommonsTime::getNowDatetime(); foreach ($sendTimeReminders as $key => $sendTime) { // リマインダーで日時が過ぎてたら、メール送らないので、除外する if (strtotime($now) > strtotime($sendTime)) { unset($sendTimeReminders[$key]); } } if (empty($sendTimeReminders)) { return null; } $this->settings[$model->alias]['reminder']['sendTimes'] = $sendTimeReminders; $this->settings[$model->alias]['reminder']['useReminder'] = 1; return $this->settings; }
/** * ブロックの公開設定をもとに現在見られるブロックなら trueを返す * * @param array $block ブロックデータ * @return bool */ public function isVisible($block) { $result = true; switch (Hash::get($block, 'Block.public_type', self::TYPE_PRIVATE)) { case self::TYPE_PRIVATE: // 非表示 $result = false; break; case self::TYPE_PUBLIC: // 表示 break; case self::TYPE_LIMITED: // 期間限定 $now = NetCommonsTime::getNowDatetime(); $start = $block['Block']['publish_start']; $end = $block['Block']['publish_end']; if ($start !== null && $start > $now) { $result = false; } if ($end !== null && $end < $now) { $result = false; } break; default: $result = false; } return $result; }
/** * 日付・時間登録作成 * * @param string $index 登録データのPOST用dataのインデックス値 * @param string $fieldName フィールド名 * @param array $question 項目データ * @param bool $readonly 読み取り専用 * @return string 複数選択肢登録のHTML */ public function dateTimeInput($index, $fieldName, $question, $readonly) { if ($readonly) { $ret = $this->value($fieldName); return $ret; } $rangeMessage = '<span class="help-block">'; $options = array(); if ($question['question_type_option'] == RegistrationsComponent::TYPE_OPTION_DATE) { $icon = 'glyphicon-calendar'; $options['format'] = 'YYYY-MM-DD'; if ($question['is_range'] == RegistrationsComponent::USES_USE) { $options['minDate'] = $question['min']; $options['maxDate'] = $question['max']; $rangeMessage .= sprintf(__d('registrations', 'Please enter at %s to %s'), date('Y-m-d', strtotime($question['min'])), date('Y-m-d', strtotime($question['max']))); } } elseif ($question['question_type_option'] == RegistrationsComponent::TYPE_OPTION_TIME) { $icon = 'glyphicon-time'; $options['format'] = 'HH:mm'; if ($question['is_range'] == RegistrationsComponent::USES_USE) { $tm = new NetCommonsTime(); $options['minDate'] = date('Y-m-d ', strtotime($tm->getNowDatetime())) . $question['min']; $options['maxDate'] = date('Y-m-d ', strtotime($tm->getNowDatetime())) . $question['max']; $rangeMessage .= sprintf(__d('registrations', 'Please enter at %s to %s'), date('H:i', strtotime($question['min'])), date('H:i', strtotime($question['max']))); } } elseif ($question['question_type_option'] == RegistrationsComponent::TYPE_OPTION_DATE_TIME) { $icon = 'glyphicon-calendar'; $options['format'] = 'YYYY-MM-DD HH:mm'; if ($question['is_range'] == RegistrationsComponent::USES_USE) { $options['minDate'] = $question['min']; $options['maxDate'] = $question['max']; $rangeMessage .= sprintf(__d('registrations', 'Please enter at %s to %s'), date('Y-m-d H:i', strtotime($question['min'])), date('Y-m-d H:i', strtotime($question['max']))); } } $options = json_encode($options); $rangeMessage .= '</span>'; $ret = '<div class="row"><div class="col-sm-4">'; $ret .= '<div class="date" >'; $ret .= $this->NetCommonsForm->input($fieldName, array('type' => 'datetime', 'div' => false, 'class' => 'form-control', 'datetimepicker' => 1, 'convert_timezone' => false, 'datetimepicker-options' => $options, 'ng-model' => 'dateAnswer[' . "'" . $question['key'] . "'" . ']', 'label' => false, 'error' => false)); $ret .= '</div>'; $ret .= '</div></div>'; $ret .= $rangeMessage; return $ret; }
/** * Called after data has been checked for errors * * @return void */ public function afterValidate() { //パスワードのハッシュ化 if (Hash::get($this->data['User'], 'password')) { App::uses('SimplePasswordHasher', 'Controller/Component/Auth'); $passwordHasher = new SimplePasswordHasher(); $this->data['User']['password'] = $passwordHasher->hash($this->data['User']['password']); $passwordAgain = $this->data['User']['password_again']; $this->data['User']['password_again'] = $passwordHasher->hash($passwordAgain); //パスワード変更日時セット $this->data['User']['password_modified'] = NetCommonsTime::getNowDatetime(); } }
/** * 時限公開のconditionsを返す * * @return array */ protected function _getPeriodConditions() { if (Current::permission('content_editable')) { return array(); } $netCommonsTime = new NetCommonsTime(); $nowTime = $netCommonsTime->getNowDatetime(); $limitedConditions[] = array('OR' => array('Registration.answer_start_period <=' => $nowTime, 'Registration.answer_start_period' => null)); $limitedConditions[] = array('OR' => array('Registration.answer_end_period >=' => $nowTime, 'Registration.answer_end_period' => null)); $timingConditions = array('OR' => array('Registration.answer_timing' => RegistrationsComponent::USES_NOT_USE, 'AND' => array('Registration.answer_timing' => RegistrationsComponent::USES_USE, $limitedConditions))); // 集計結果の表示は登録フォーム登録が始まっていることが前提 $totalLimitPreCond = array('OR' => array('Registration.answer_timing' => RegistrationsComponent::USES_NOT_USE, 'AND' => array('Registration.answer_timing' => RegistrationsComponent::USES_USE, 'OR' => array('Registration.answer_start_period <=' => $nowTime, 'Registration.answer_start_period' => null)))); $totalLimitCond[] = array('OR' => array('Registration.total_show_start_period <=' => $nowTime, 'Registration.total_show_start_period' => null)); $totalTimingCond = array('Registration.is_total_show' => RegistrationsComponent::USES_USE, $totalLimitPreCond, 'OR' => array('Registration.total_show_timing' => RegistrationsComponent::USES_NOT_USE, $totalLimitCond)); $timingConditions['OR'][] = $totalTimingCond; if (Current::permission('content_creatable')) { $timingConditions['OR']['Registration.created_user'] = Current::read('User.id'); } return $timingConditions; }
/** * 24時間以上Registrationと関連づいてないゴミブロックを削除する * * @return void */ protected function _deleteNotUsedBlocks() { // 24時間以上Registrationsと関連づいてないブロックを探す。 $date = new DateTime(NetCommonsTime::getNowDatetime()); $date->sub(new DateInterval('P1D')); $options = ['conditions' => ['Block.plugin_key' => 'registrations', 'Registration.id' => null, 'Block.modified <' => $date->format('Y-m-d H:i:s')], 'joins' => [['table' => $this->Registration->table, 'alias' => $this->Registration->alias, 'type' => 'LEFT', 'conditions' => array('Block.id = Registration.block_id')]], 'fields' => ['Block.id']]; $blocks = $this->Block->find('all', $options); $blockIds = Hash::extract($blocks, '{n}.Block.id'); if (empty($blockIds)) { return; } // 削除実行 $this->Block->begin(); $this->Block->deleteAll(['Block.id' => $blockIds]); $this->Block->commit(); }
/** * 検索可能のフィールドをチェックして、検索不可なフィールドは削除する * * @param array $field フィールド * @param array $setting セッティングモード(日時型のみ使用) * @param array $value 値 * @param string $defaultSign デフォルトの符号 * @return array array(符号, SQL値) */ protected function _creanSearchCondition($field, $setting, $value, $defaultSign = null) { $userAttributes = $this->UserAttribute->getUserAttributesForLayout(); $dataType = Hash::extract($userAttributes, '{n}.{n}.{n}.UserAttributeSetting[user_attribute_key=' . $field . ']'); $dataTypeKey = Hash::get($dataType, '0.data_type_key', ''); $forwardTypes = array(DataType::DATA_TYPE_TEXT, DataType::DATA_TYPE_TEXTAREA, DataType::DATA_TYPE_EMAIL); $optionTypes = array(DataType::DATA_TYPE_RADIO, DataType::DATA_TYPE_SELECT, DataType::DATA_TYPE_CHECKBOX, DataType::DATA_TYPE_PREFECTURE, DataType::DATA_TYPE_TIMEZONE, DataType::DATA_TYPE_MULTIPLE_SELECT); if ($dataTypeKey === DataType::DATA_TYPE_IMG) { if ($value) { $sign = ' NOT'; } else { $sign = $defaultSign; } $value = null; } elseif (in_array($field, UserAttribute::$typeDatetime, true) || $dataTypeKey === DataType::DATA_TYPE_DATETIME) { //日付型の場合 if ($setting === self::MORE_THAN_DAYS) { //○日以上前(○日以上ログインしていない) $sign = ' <='; } else { //○日以内(○日以内ログインしている) $sign = ' >='; } $date = new DateTime(NetCommonsTime::getNowDatetime()); $date->sub(new DateInterval(sprintf('P%dD', (int) $value))); $value = $date->format('Y-m-d H:i:s'); } elseif (in_array($dataTypeKey, $forwardTypes, true) || in_array($field, ['created_user', 'modified_user'], true)) { // テキスト型、テキストエリア型、メールアドレス型、作成者、更新者の場合 // ->あいまい検索※今後、MatchAgainstもしくは、前方一致にする必要あり。 $sign = ' LIKE'; $value = '%' . $value . '%'; } elseif (in_array($dataTypeKey, $optionTypes, true)) { $sign = $defaultSign; $userAttribute = Hash::extract($userAttributes, '{n}.{n}.{n}.UserAttribute[key=' . $field . ']'); $userAttrId = Hash::get($userAttribute, '0.id'); $options = Hash::extract($userAttributes, '{n}.{n}.{n}.UserAttributeChoice.{n}[user_attribute_id=' . $userAttrId . ']'); $value = Hash::get(Hash::extract($options, '{n}[key=' . $value . ']', array()), '0.' . Hash::get($this->readableFields, $field . '.' . 'option_field', '')); } else { $sign = $defaultSign; } return array($sign, $value); }