/** * Show truncated long text and hide full version for flyout * * When there is a lot of text for a small area, this shows just the * truncated lead. The full text is in an element that is hidden. * Javascript or css can implement a flyout to show the full thing. * * Attributes: * $filed.leadPlus => * div // div containing the hidden full text * p // div > p containg the full text * span // div + span containg truncated text * truncate // [truncate][limit] charcter count in truncated text * * @param type $helper */ public function leadPlus($field) { if (!$this->hasUuid()) { $uuid = new Uuid(); } else { $uuid = $this->helper->entity->_uuid; } // established passed and default attributes $passed_attributes = $this->helper->attributes("{$field}.leadPlus"); $default = new \Cake\Collection\Collection(['full_text' => ['span' => ['id' => $uuid->uuid('full'), 'class' => 'full_text', 'style' => 'cursor: pointer; display: none;', 'onclick' => 'var id = this.id.replace("full", "truncated"); this.style.display = "none"; document.getElementById(id).style.display = "inline-block";']], 'truncated_text' => ['span' => ['id' => $uuid->uuid('truncated'), 'class' => 'truncated_text', 'style' => 'cursor: pointer; display: inline-block;', 'onclick' => 'var id = this.id.replace("truncated", "full"); this.style.display = "none"; document.getElementById(id).style.display = "inline-block";']], 'truncate' => ['limit' => [100]], 'p' => []]); // intermediary values for calculations $key_template = $default->map(function ($value, $key) { return null; }); // this yeilds array with all keys. values will be int if passed in, null if default $attribute_keys = array_flip(array_keys($passed_attributes)) + $key_template->toArray(); // get attributes to use during rendering $attribute = $default->map(function ($value, $key) use($attribute_keys, $passed_attributes) { if (is_null($attribute_keys[$key])) { return $value; } else { return array_merge($value, $passed_attributes[$key]); } })->toArray(); // output // SOMEONE SORT THIS OUT TO MAKE IT HAVE DEFAULT out-of-the-box BEHAVIOR $hidden = $this->helper->Html->tag('span', $this->helper->entity->{$field}, $attribute['full_text']['span']); $text = $this->helper->Html->tag('span', Text::truncate($this->helper->entity->{$field}, $attribute['truncate']['limit']), $attribute['truncated_text']['span']); return $this->helper->Html->tag('p', $text . $hidden, $attribute['p']); }
public function upload() { try { $audioTable = TableRegistry::get('Audios'); $dateTimeUtc = new \DateTimeZone('UTC'); $now = new \DateTime('now', $dateTimeUtc); // Generate file name $serverDir = TMP . 'files' . DS; $serverFileName = Text::uuid() . '.wav'; $uploadFullPath = $serverDir . $serverFileName; // Move file to temp location if (!move_uploaded_file($_FILES['file']['tmp_name'], $uploadFullPath)) { throw new \Exception('Cannot copy file to tmp location: ' . $uploadFullPath); } $uploadFullPath = $this->__convertToPhoneAudio($uploadFullPath); $data = ['file_name' => $_FILES['file']['name'], 'server_dir' => $serverDir, 'server_name' => $serverFileName, 'create_datetime' => $now]; $audio = $audioTable->newEntity($data); $audioTable->save($audio); $response['status'] = 1; $response['audioId'] = $audio->audio_id; } catch (\Excaption $ex) { $response['status'] = 0; $response['message'] = $ex->getMessage(); } $this->set(compact('response')); $this->set('_serialize', ['response']); }
/** * Create bootstrap tabs. * * @param array $data * @param string $id * @return string * @SuppressWarnings(PHPMD.ShortVariable) */ public function tabs($id, array $data = []) { $i = 0; $output = []; foreach ($data as $key => $options) { $i++; $title = !is_array($options) ? $options : $key; $alias = Text::slug((string) Inflector::underscore($key), '-'); if (is_string($options)) { $options = []; } $_options = ['linkOptions' => ['data-toggle' => 'tab']]; if (isset($options['title'])) { $title = $options['title']; unset($options['title']); } $_options['linkOptions']['title'] = $title; if ($i == 1) { $_options = $this->addClass($_options, 'active'); } $options = Hash::merge($_options, $options); $linkOptions = $options['linkOptions']; unset($options['linkOptions']); $link = $this->Html->link($title, '#' . $alias, $linkOptions); $output[] = $this->Html->tag('li', $link, $options); } return $this->Html->tag('ul', implode('', $output), ['class' => 'nav nav-tabs', 'id' => $id]); }
/** * */ public function getDescription($data, $entity, $options) { $content = ''; extract($options); if (isset($fields)) { if (is_array($fields)) { foreach ($fields as $field) { if ($entity->has($field)) { $temp = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $entity->{$field}); $temp = preg_replace('/&[a-z]+;/', '', $temp); $temp = preg_replace('/<\\/[a-z]+><[a-z]+>/', ' ', $temp); $temp = preg_replace('/[\\s]{1,}/', ' ', $temp); $content .= strip_tags($temp); } } } else { if ($entity->has($fields)) { $temp = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $entity->{$fields}); $temp = preg_replace('/&[a-z]+;/', '', $temp); $temp = preg_replace('/<\\/[a-z]+><[a-z]+>/', ' ', $temp); $temp = preg_replace('/[\\s]{1,}/', ' ', $temp); $content .= strip_tags($temp); } } } return Text::truncate($content, 160, ['ellipsis' => '', 'exact' => false, 'html' => false]); }
/** * Add method * * @return void Redirects on successful add, renders view otherwise. */ public function add() { $boletos = $this->Boletoxretornos->Boletos->find('all')->toArray(); $arrayBoletos; $opBoletos; $i = 0; foreach ($boletos as $x) { $arrayBoletos[$i] = $x->id; $opBoletos[$i] = $x->inr_boleto; $i++; } $boletoxretorno = $this->Boletoxretornos->newEntity(); if ($this->request->is('post')) { $boletoxretorno = $this->Boletoxretornos->patchEntity($boletoxretorno, $this->request->data); $boletoxretorno->id = Text::uuid(); $boletoxretorno->boleto_id = $arrayBoletos[$boletoxretorno->boleto_id]; if ($this->Boletoxretornos->save($boletoxretorno)) { $this->Flash->success(__('O retorno foi salvo.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('O retorno não pôde ser salvo. Tente novamente.')); } } $this->set(compact('boletoxretorno', 'opBoletos')); $this->set('_serialize', ['boletoxretorno']); }
/** * Add method * * @return void Redirects on successful add, renders view otherwise. */ public function add() { $participantes = $this->Boletos->Participantes->find('all')->toArray(); $arrayParticipantes; $opParticipantes; $i = 0; foreach ($participantes as $x) { $opParticipantes[$i] = $x['cnm_participante']; $arrayParticipantes[$i] = $x['id']; $i++; } $boleto = $this->Boletos->newEntity(); if ($this->request->is('post')) { $boleto = $this->Boletos->patchEntity($boleto, $this->request->data); $boleto->id = Text::uuid(); $boleto->participante_id = $arrayParticipantes[$boleto->participante_id]; if ($this->Boletos->save($boleto)) { $this->Flash->success(__('O boleto foi salvo.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('O boleto não pôde ser salvo. Tente novamente.')); } } $this->set(compact('boleto', 'opParticipantes')); $this->set('_serialize', ['boleto']); }
/** * Add method * * @return void Redirects on successful add, renders view otherwise. */ public function add($idSub) { $submissoes = $this->Submissaoxcoautores->Submissoes->find('all')->toArray(); $i = 0; $arraySubmissoes; $opSubmissoes; foreach ($submissoes as $x) { $arraySubmissoes[$i] = $x->id; $opSubmissoes[$i] = $x->ctl_submissao; $i++; } $submissaoxcoautore = $this->Submissaoxcoautores->newEntity(); if ($this->request->is('post')) { $submissaoxcoautore = $this->Submissaoxcoautores->patchEntity($submissaoxcoautore, $this->request->data); $submissaoxcoautore->id = Text::uuid(); $submissaoxcoautore->submissao_id = $idSub; //$arraySubmissoes[$submissaoxcoautore->submissao_id]; if ($this->Submissaoxcoautores->save($submissaoxcoautore)) { $this->Flash->success(__('O coautor foi salvo.')); return $this->redirect(['controller' => 'Submissoes', 'action' => 'index']); } else { $this->Flash->error(__('O coautor não pôde ser salvo. Tente novamente.')); } } $this->set(compact('submissaoxcoautore', 'opSubmissoes')); $this->set('_serialize', ['submissaoxcoautore']); }
/** * Gets the tag slug (virtual field) * @return string|null */ protected function _getSlug() { if (empty($this->_properties['tag'])) { return null; } return Text::slug($this->_properties['tag']); }
public function add() { $clientInfo = $this->ClientInfos->newEntity(); if ($this->request->is('post')) { $userid = Text::uuid(); $contactid = Text::uuid(); $clientid = Text::uuid(); $this->loadModel('Users'); $users = $this->Users->newEntity(); $users = $this->Users->patchEntity($users, $this->request->data['Users']); $this->Users->save($users); $this->loadModel('ClientInfos'); $clientInfos = $this->ClientInfos->newEntity(); $clientInfos = $this->ClientInfos->patchEntity($clientInfos, $this->request->data['ClientInfos']); $this->ClientInfos->save($clientInfos); $this->loadModel('ClientContacts'); $clientContacts = $this->ClientContacts->newEntity(); $clientContacts = $this->ClientContacts->patchEntity($clientContacts, $this->request->data['ClientContacts']); $this->ClientContacts->save($clientContacts); return $this->redirect(['controller' => 'ClientDevices', 'action' => 'add']); } $clientTypes = $this->ClientInfos->ClientTypes->find('list', ['limit' => 200]); $companyTypes = $this->ClientInfos->CompanyTypes->find('list', ['limit' => 200]); $this->set(compact('clientInfo', 'clientTypes', 'companyTypes')); $this->set('_serialize', ['clientInfo']); }
/** * Render a text widget or other simple widget like email/tel/number. * * This method accepts a number of keys: * * - `name` The name attribute. * - `val` The value attribute. * - `escape` Set to false to disable escaping on all attributes. * * Any other keys provided in $data will be converted into HTML attributes. * * @param array $data The data to build an input with. * @param \Cake\View\Form\ContextInterface $context The current form context. * @return string */ public function render(array $data, ContextInterface $context) { $data += ['name' => '', 'val' => null, 'type' => 'text', 'mode' => 'datetime', 'escape' => true, 'readonly' => true, 'templateVars' => []]; // mode value and class $mode = $data['mode']; $hval = $data['value'] = $data['val']; $data['class'] = $data['type']; unset($data['val'], $data['mode']); // transform into frozen time if not already if (!($data['value'] instanceof FrozenTime || $data['value'] instanceof FrozenDate)) { $data['value'] = new FrozenTime($data['value']); } // transform values if ($mode == 'datetime') { $hval = $data['value']->format('Y-m-d H:i:s'); $data['value'] = $data['value']->format('d-M-Y H:i:s'); } if ($mode == 'date') { $hval = $data['value']->format('Y-m-d'); $data['value'] = $data['value']->format('d-M-Y'); } if ($mode == 'time') { $hval = $data['value'] = $data['value']->format('H:i:s'); } // render $rand = Text::uuid(); return "<div id='{$rand}' style='position: relative;'>" . $this->_templates->format('input', ['name' => $data['name'], 'type' => 'hidden', 'attrs' => $this->_templates->formatAttributes(['value' => $hval])]) . $this->_templates->format('input', ['name' => $data['name'] . '-' . $rand, 'type' => $mode, 'templateVars' => $data['templateVars'], 'attrs' => $this->_templates->formatAttributes($data, ['name', 'type'])]) . "<div id='dtpicker-{$rand}'></div><scriptend>\$(document).ready(Backend.DTPicker('{$rand}', '{$mode}'));</scriptend></div>"; }
/** * Slug a field passed in the default config with its replacement. * @param $value The string that needs to be processed * @param $config The config array is passed here * @return string */ private function slug($value = null, $config = []) { // generate slug $slug = strtolower(Text::slug($value, $config['replacement'])); // unique slug? if ($config['unique']) { // does the slug already exist in db? $field = $this->_table->alias() . '.' . $config['slug']; $conditions = [$field => $slug]; $suffix = ''; $i = 0; // loop till unique slug is found while ($this->_table->exists($conditions)) { $i++; $suffix = $config['replacement'] . $i; $conditions[$field] = $slug . $suffix; } // got suffix? append it if ($suffix) { $slug .= $suffix; } } // return slug return $slug; }
public function ajaxSendCall() { try { $numberListTable = TableRegistry::get('NumberLists'); $sendQueueTable = TableRegistry::get('SendQueues'); $numberTable = TableRegistry::get('Numbers'); // Check if list exists $numberList = $numberListTable->find('all', ['conditions' => ['number_list_id' => $this->request->data['call']['number_list_id']]]); if (!$numberList->count()) { throw new \Exception('Cannot locate list.'); } $number = $numberTable->find('all', ['conditions' => ['number_list_id' => $this->request->data['call']['number_list_id']]]); $numberCount = $number->count(); if (!$numberCount) { throw new \Exception('No numbers in the list'); } $data = ['unique_id' => Text::uuid(), 'type' => 2, 'number_list_id' => $this->request->data['call']['number_list_id'], 'status' => 0, 'message' => $this->request->data['call']['message'], 'audio_id' => $this->request->data['call']['audio_id'], 'request_by' => null, 'total' => $numberCount, 'create_datetime' => new \DateTime('now', new \DateTimeZone('UTC'))]; $sendQueue = $sendQueueTable->newEntity($data); $sendQueueTable->save($sendQueue); // Hit the cron shell_exec(ROOT . DS . 'bin' . DS . 'cake SendCall ' . $sendQueue->send_queue_id . ' > /dev/null 2>/dev/null &'); $response['status'] = 1; $response['sendQueueId'] = $sendQueue->send_queue_id; $response['numberCount'] = $numberCount; } catch (\Exception $ex) { $response['status'] = 0; $response['message'] = $ex->getMessage(); } $this->set(compact('response')); $this->set('_serialize', ['response']); }
/** * Run Method. * * Write your database seeder using this method. * * More information on writing seeders is available here: * http://docs.phinx.org/en/latest/seeding.html * * @return void */ public function run() { $time = date("Y-m-d H:i:s"); $data = [['id' => Text::uuid(), 'email' => '*****@*****.**', 'username' => 'administrator', 'realname' => 'Administrator', 'password' => (new DefaultPasswordHasher())->hash('adminadmin'), 'created' => $time, 'modified' => $time, 'role' => 'admin', 'status' => '1', 'preferences' => json_encode(Cake\Core\Configure::read('cms.defaultUserPreferences'))]]; $table = $this->table('users'); $table->insert($data)->save(); }
/** * Custom finder for map the ntofications. * * @param \Cake\ORM\Query $query The query finder. * @param array $options The options passed in the query builder. * * @return \Cake\ORM\Query */ public function findMap(Query $query, array $options) { return $query->formatResults(function ($notifications) use($options) { return $notifications->map(function ($notification) use($options) { $notification->data = unserialize($notification->data); switch ($notification->type) { case 'conversation.reply': $username = $notification->data['sender']->username; $conversationTitle = Text::truncate($notification->data['conversation']->title, 50, ['ellipsis' => '...', 'exact' => false]); //Check if the creator of the conversation is the current user. if ($notification->data['conversation']->user_id === $options['session']->read('Auth.User.id')) { $notification->text = __('<strong>{0}</strong> has replied in your conversation <strong>{1}</strong>.', h($username), h($conversationTitle)); } else { $notification->text = __('<strong>{0}</strong> has replied in the conversation <strong>{1}</strong>.', h($username), h($conversationTitle)); } $notification->link = Router::url(['controller' => 'conversations', 'action' => 'go', $notification->data['conversation']->last_message_id, 'prefix' => false]); break; case 'bot': $notification->text = __('Welcome on <strong>{0}</strong>! You can now post your first comment in the blog.', \Cake\Core\Configure::read('Site.name')); $notification->link = Router::url(['controller' => 'blog', 'action' => 'index', 'prefix' => false]); $notification->icon = $notification->data['icon']; break; case 'badge': $notification->text = __('You have unlock the badge "{0}".', $notification->data['badge']->name); $notification->link = Router::url(['_name' => 'users-profile', 'id' => $notification->data['user']->id, 'slug' => $notification->data['user']->username, '#' => 'badges', 'prefix' => false]); break; } return $notification; }); }); }
/** * group link function * @param string $title title for menu link * @param array $urls force array * @param array $options configure for link * @return string inside <li> tag */ public function groupLink($title, array $urls = [], array $options = []) { $result = '<li class="panel panel-default dropdown">'; $controller = $this->Html->request->controller; foreach ($urls as $k => $v) { if (isset($v[1]) && $controller === $v[1]['controller']) { $result = '<li class="active panel panel-default dropdown">'; break; } } $collapseId = Text::uuid(); $result .= $this->Html->link($title, '#' . $collapseId, ['data-toggle' => 'collapse', 'escape' => false]); $result .= '<div id="' . $collapseId . '" class="panel-collapse collapse">'; $result .= '<div class="panel-body">'; $result .= '<ul class="nav navbar-nav">'; foreach ($urls as $k => $v) { if (empty($v[0]) || empty($v[1])) { continue; } $result .= '<li>' . $this->Html->link($v[0], $v[1]) . '</li>'; } $result .= '</ul>'; $result .= '</div>'; $result .= '</div>'; $result .= '</li>'; return $result; }
/** * @return string */ public function getName() { if (empty($this->name)) { $this->name = Text::uuid(); } return $this->name; }
protected function _getExcerpt() { if (array_key_exists('body', $this->_properties)) { return Text::excerpt($this->_properties['body'], 'method', 400); } return null; }
public function send($data, $old_data = null) { if (!empty($data)) { $filename = $data['name']; $file_tmp_name = $data['tmp_name']; $dir_root = WWW_ROOT . 'img' . DS . 'uploads'; $dir = 'uploads'; $allowed = array('png', 'jpg', 'jpeg'); if (!in_array(substr(strrchr($filename, '.'), 1), $allowed)) { return false; } elseif (is_uploaded_file($file_tmp_name)) { if ($old_data != null) { $old_file = substr(strrchr($old_data, DS), 1); if (file_exists($dir_root . DS . $old_file)) { unlink($dir_root . DS . $old_file); } } $file = Text::uuid() . '-' . $filename; // enregistrement du nom du fichier $file_root = $dir_root . DS . $file; // definition du chemin ou sera stocker le fichier move_uploaded_file($file_tmp_name, $file_root); // deplacement du fichier $filedb = $dir . DS . $file; // definition du chemin qui sera utilise dans la base de donnee return $filedb; } } }
private static function request_id() { if (empty(self::$_request_id)) { self::$_request_id = Text::uuid(); } return self::$_request_id; }
/** * Add method * * @return void Redirects on successful add, renders view otherwise. */ public function add() { $municipios = $this->Locais->Municipios->find('all')->toArray(); $array; $op; $i = 0; foreach ($municipios as $x) { $op[$i] = $x['cnm_municipio'] . ' (' . $x['ccd_municipio'] . ')'; $array[$i] = $x['id']; $i++; } $local = $this->Locais->newEntity(); if ($this->request->is('post')) { $local = $this->Locais->patchEntity($local, $this->request->data); $local->id = Text::uuid(); $local->municipio_id = $array[$local->municipio_id]; if ($this->Locais->save($local)) { $this->Flash->success(__('O local foi salvo.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('O local não pôde ser salvo. Tente novamente.')); } } $this->set(compact('local', 'op')); $this->set('_serialize', ['local']); }
public static function body($alias, $vars = null) { if (!$vars) { $vars = []; } $content = self::get($alias, 'body'); return Text::insert($content, $vars); }
/** * Gets a brief description of 80 characters long. * * @return string */ protected function _getBriefDescription() { $description = $this->get('description'); if (empty($description)) { return '---'; } return Text::truncate($description, 80); }
public function beforeSave(Event $event) { $entity = $event->data['entity']; if ($entity->isNew()) { $entity->api_key = Security::hash(Text::uuid()); } return true; }
/** * Wrapper para Configure::load(). * Faz uma verificação para ver se o plugin está instalado. (@see PluginStarter::install()). * * @param string $pluginName O nome do plugin a ser carregado. * @return bool O retorno do chamado Configure::load(). */ public function load($pluginName) { $settingsFile = $this->pluginInstallationFolder . $pluginName . DS . 'settings.php'; if (!file_exists($settingsFile)) { $this->install($pluginName); } $configPath = Text::insert('Plugins/:plugin/settings', ['plugin' => $pluginName]); return Configure::load($configPath); }
/** * Conditionally adds the `_auditTransaction` and `_auditQueue` keys to $options. They are * used to track all changes done inside the same transaction. * * @param Cake\Event\Event The Model event that is enclosed inside a transaction * @param Cake\Datasource\EntityInterface $entity The entity that is to be saved * @param ArrayObject $options The options to be passed to the save or delete operation * @return void */ public function injectTracking(Event $event, EntityInterface $entity, ArrayObject $options) { if (!isset($options['_auditTransaction'])) { $options['_auditTransaction'] = Text::uuid(); } if (!isset($options['_auditQueue'])) { $options['_auditQueue'] = new SplObjectStorage(); } }
/** * Generate slug. * * @param string $string Input string. * @param string $replacement Replacement string. * @return string Sluggified string. */ public function slug($string, $replacement = '-') { $config = $this->config; $config['replacement'] = $replacement; $string = Text::slug($string, $config); if ($config['lowercase']) { return mb_strtolower($string); } return $string; }
function __construct(Api $api, array $assertions = [], $id = null) { $this->api = $api; $this->assertions = $assertions; $this->report = new Report(); if (is_null($id)) { $id = Text::uuid(); } $this->id = $id; }
/** * Test saving new records allows manual uuids * * @return void */ public function testSaveNewSpecificId() { $id = Text::uuid(); $entity = new Entity(['id' => $id, 'name' => 'shiny and new', 'published' => true]); $table = TableRegistry::get('uuiditems'); $this->assertSame($entity, $table->save($entity)); $row = $table->find('all')->where(['id' => $id])->first(); $this->assertNotEmpty($row); $this->assertSame($id, strtolower($row->id)); $this->assertSame($entity->name, $row->name); }
/** * Register a new collection. * * @param string $id The collection identifier. * @param array $options The collection options. */ public static function register($id, $options) { $id = (string) $id; if (self::exists($id)) { user_error(Text::insert('A collection with id ":id" is already registered.', ['id' => $id])); return; } $defaults = ['model' => 'Plugin.Model', 'displayName' => 'Translated Name']; $options = array_merge($defaults, $options); self::_instance()->_items[$id] = $options; }
public function api_fetch_all() { $this->autoRender = false; // Objetos de tabela $messages_table = TableRegistry::get("Messages"); // Sessão de admin $user_id = $this->userLogged['user_id']; // Se ele for um aluno if ($this->userLogged['table'] == 'Users') { } // Busca todas as mensagens do usuário logado $where = ['Messages.user_id' => $user_id]; $messages = $messages_table->find()->where($where)->contain(['MessageRecipients', 'MessageReplies'])->order(['id' => 'DESC'])->all()->toArray(); $atores_global = $this->getAtores(); // Itera todas as mensagens foreach ($messages as $key_message => $message) { // Data de envio formatada $message->date = $message->created->format("d M"); // Destinatário $message->to = []; // Respostas $message->replies = []; // Autor $message->from = ""; // Resumo $message->excerpt = Text::truncate($message->content, 140, ['ellipsis' => '...', 'exact' => false]); // Itera todos os atores foreach ($atores_global as $ator_label => $atores) { foreach ($atores as $ator) { if ($ator->id == $message->model_id && $ator_label == $message->model) { $message->from = $ator->full_name; } } } // Itera todos os recipientes e adiciona ao $to foreach ($message->message_recipients as $message_recipient) { foreach ($atores_global[$message_recipient->model] as $ator) { if ($ator->id == $message_recipient->model_id) { $message->to[] = $ator->full_name; } } } // Itera todas as respostas e adiciona a $replies foreach ($message->message_replies as $reply) { foreach ($atores_global[$reply->model] as $ator) { if ($ator->id == $reply->model_id) { $message->replies[] = ['content' => $reply->content, 'author' => $ator->full_name]; } } } } // Retorna em JSON echo json_encode($messages); }