/** * Method that renders Entity values through Field Handler Factory. * * @param Cake\ORM\Entity $entity Entity instance * @param Cake\ORM\Table|string $table Table instance * @param array $fields Fields to prettify * @return void */ protected function _prettify(Entity $entity, $table, array $fields = []) { if (!$this->__fhf instanceof FieldHandlerFactory) { $this->__fhf = new FieldHandlerFactory(); } if (empty($fields)) { $fields = array_keys($entity->toArray()); } foreach ($fields as $field) { // handle belongsTo associated data if ($entity->{$field} instanceof Entity) { $tableName = $table->association($entity->{$field}->source())->className(); $this->_prettify($entity->{$field}, $tableName); } // handle hasMany associated data if (is_array($entity->{$field})) { if (empty($entity->{$field})) { continue; } foreach ($entity->{$field} as $associatedEntity) { if (!$associatedEntity instanceof Entity) { continue; } $tableName = $table->association($associatedEntity->source())->className(); $this->_prettify($associatedEntity, $tableName); } } $renderOptions = ['entity' => $entity]; $entity->{$field} = $this->__fhf->renderValue($table instanceof Table ? $table->registryAlias() : $table, $field, $entity->{$field}, $renderOptions); } }
/** * Get related model's properties. * * @param mixed $table related table instance or name * @param sting $data query parameter value * @return mixed */ protected function _getRelatedProperties($table, $data) { if (!is_object($table)) { $tableName = $table; $table = TableRegistry::get($tableName); } else { $tableName = $table->registryAlias(); } $result['id'] = $data; if (method_exists($table, 'getConfig') && is_callable([$table, 'getConfig'])) { $result['config'] = $table->getConfig(); } // display field $result['displayField'] = $table->displayField(); // get associated entity record $result['entity'] = $this->_getAssociatedRecord($table, $data); // get related table's displayField value if (!empty($result['entity'])) { // Pass the value through related field handler // to properly display the user-friendly label. $fhf = new FieldHandlerFactory($this->cakeView); $result['dispFieldVal'] = $fhf->renderValue($table, $table->displayField(), $result['entity']->{$table->displayField()}, ['renderAs' => RelatedFieldHandler::RENDER_PLAIN_VALUE]); } else { $result['dispFieldVal'] = null; } // get plugin and controller names list($result['plugin'], $result['controller']) = pluginSplit($tableName); return $result; }
public function testRenderValue() { $result = $this->fhf->renderValue($this->FooTable, 'id', 'blah'); $this->assertRegexp('/blah/i', $result, "Rendering value 'blah' for 'id' field has no 'blah'"); }
/** * Lookup CRUD action events handling logic. * * @return \Cake\Network\Response */ public function lookup() { $this->Crud->on('beforeLookup', function (Event $event) { if (!empty($this->request->query['query'])) { $typeaheadFields = []; // Get typeahead fields from configuration if (method_exists($this->{$this->name}, 'typeaheadFields') && is_callable([$this->{$this->name}, 'typeaheadFields'])) { $typeaheadFields = $this->{$this->name}->typeaheadFields(); } // If there are no typeahead fields configured, use displayFields() if (empty($typeaheadFields)) { $typeaheadFields[] = $this->{$this->name}->displayField(); } $conditions = []; if (count($typeaheadFields) > 1) { $conditions['OR'] = []; foreach ($typeaheadFields as $field) { $conditions['OR'][] = [$field . ' LIKE' => '%' . $this->request->query['query'] . '%']; } } elseif (count($typeaheadFields) == 1) { $conditions[] = [$typeaheadFields[0] . ' LIKE' => '%' . $this->request->query['query'] . '%']; } else { throw new \RuntimeException("No typeahead or display field configured for " . $this->name); } $this->paginate['conditions'] = $conditions; } }); $this->Crud->on('afterLookup', function (Event $event) { // Properly populate display values for the found entries. // This will recurse into related modules and get display // values as deep as needed. $entities = $event->subject()->entities; $event->subject()->entities = []; foreach ($entities as $key => $entity) { $fhf = new FieldHandlerFactory(); // We need plain display value. It'll be properly wrapped // in styling only at the top level. $entity = $fhf->renderValue($this->{$this->name}, $this->{$this->name}->displayField(), $entity, ['renderAs' => RelatedFieldHandler::RENDER_PLAIN_VALUE]); $event->subject()->entities[$key] = $entity; } }); return $this->Crud->execute(); }
/** * sendCalendarReminder method * Notification about the reminder is sent only * when the record belonds to anyone. * @param Cake\Event $event from the afterSave * @param Cake\Datasource\EntityInterface $entity from the afterSave * @return array|bool $sent on whether the email was sent */ public function sendCalendarReminder(Event $event, EntityInterface $entity) { $sent = false; $currentUser = null; //get applications's timezone $timezone = Time::now()->format('e'); $dtz = new \DateTimeZone($timezone); $table = $event->subject(); //get attendees Table for the event if (method_exists($table, 'getConfig') && is_callable([$table, 'getConfig'])) { $config = $table->getConfig(); $remindersTo = $table->getTableAllowRemindersField(); } // skip if attendees Table is not defined if (empty($remindersTo)) { return $sent; } // Figure out which field is a reminder one $reminderField = $table->getReminderFields(); if (empty($reminderField) || !is_array($reminderField)) { return $sent; } $reminderField = $reminderField[0]; if (!is_array($reminderField) || empty($reminderField['name'])) { return $sent; } $reminderField = $reminderField['name']; // Skip sending email if reminder field is empty if (empty($entity->{$reminderField})) { return $sent; } $attendeesFields = $this->_getAttendeesFields($table, ['tables' => $remindersTo]); // skip if no attendees fields found if (empty($attendeesFields)) { return $sent; } // skip if none of the required fields was modified $requiredFields = array_merge((array) $reminderField, $attendeesFields); if (!$this->_requiredFieldsModified($entity, $requiredFields)) { return $sent; } /* * Figure out the subject of the email * * This should happen AFTER the `$table->getConfig()` call, * in case the display field of the table is changed from the * configuration. * * Use singular of the table name and the value of the entity's display field. * For example: "Call: Payment remind" or "Lead: Qobo Ltd". */ $fhf = new FieldHandlerFactory(); $emailSubjectValue = $fhf->renderValue($table, $table->displayField(), $entity->{$table->displayField()}, ['renderAs' => 'plain']); $eventSubject = $emailSubjectValue ?: 'reminder'; $emailSubject = Inflector::singularize($table->alias()) . ": " . $eventSubject; $emailContent = Inflector::singularize($table->alias()) . " information was "; // If the record is being updated, prefix the above subject with "(Updated) ". if (!$entity->isNew()) { $emailSubject = '(Updated) ' . $emailSubject; $emailContent .= "updated"; } else { $emailContent .= "created"; } $emails = $this->_getAttendees($table, $entity, $attendeesFields); if (empty($emails)) { return $sent; } if (method_exists($table, 'getCurrentUser') && is_callable([$table, 'getCurrentUser'])) { $currentUser = $table->getCurrentUser(); $emailContent .= " by " . $currentUser['email']; } // append changelog if entity is not new if (!$entity->isNew()) { $emailContent .= "\n\n" . $this->_getChangelog($entity); } foreach ($emails as $email) { $vCalendar = new \Eluceo\iCal\Component\Calendar('//EN//'); $vAttendees = $this->_getEventAttendees($emails); $vEvent = $this->_getCalendarEvent($entity, ['dtz' => $dtz, 'organizer' => $email, 'subject' => $emailSubject, 'attendees' => $vAttendees, 'field' => $reminderField, 'timezone' => $timezone]); $vEvent->setAttendees($vAttendees); $vCalendar->addComponent($vEvent); $headers = "Content-Type: text/calendar; charset=utf-8"; $headers .= 'Content-Disposition: attachment; filename="event.ics"'; $emailer = new Email('default'); $emailer->to($email)->setHeaders([$headers])->subject($emailSubject)->attachments(['event.ics' => ['contentDisposition' => true, 'mimetype' => 'text/calendar', 'data' => $vCalendar->render()]]); $sent = $emailer->send($emailContent); } return $sent; }