/** */ protected function _content() { global $registry, $prefs; if (!empty($this->_params['show_notepad'])) { $shares = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Share')->create(); } $html = ''; $memos = Mnemo::listMemos($prefs->getValue('sortby'), $prefs->getValue('sortdir')); foreach ($memos as $id => $memo) { $html .= '<tr>'; if (!empty($this->_params['show_actions'])) { $editImg = Horde_Themes::img('edit.png'); $editurl = Horde::url('memo.php')->add(array('memo' => $memo['memo_id'], 'memolist' => $memo['memolist_id'])); $html .= '<td width="1%">' . Horde::link(htmlspecialchars(Horde::url($editurl, true)->add('actionID', 'modify_memo')), _("Edit Note")) . Horde::img($editImg, _("Edit Note")) . '</a></td>'; } if (!empty($this->_params['show_notepad'])) { $html .= '<td>' . htmlspecialchars(Mnemo::getLabel($shares->getShare($memo['memolist_id']))) . '</td>'; } $viewurl = Horde::url('view.php')->add(array('memo' => $memo['memo_id'], 'memolist' => $memo['memolist_id'])); $html .= '<td>' . Horde::linkTooltip(htmlspecialchars(Horde::url($viewurl, true)), '', '', '', '', $memo['body'] != $memo['desc'] ? Mnemo::getNotePreview($memo) : '') . (strlen($memo['desc']) ? htmlspecialchars($memo['desc']) : '<em>' . _("Empty Note") . '</em>') . '</a> <ul class="horde-tags">'; foreach ($memo['tags'] as $tag) { $html .= '<li>' . htmlspecialchars($tag) . '</li>'; } $html .= '</ul></td></tr>'; } if (!$memos) { return '<p><em>' . _("No notes to display") . '</em></p>'; } return '<table cellspacing="0" width="100%" class="linedRow">' . $html . '</table>'; }
/** */ protected function _params() { global $prefs; $memos = Mnemo::listMemos($prefs->getValue('sortby'), $prefs->getValue('sortdir')); $notes = array(); foreach ($memos as $memo) { $notes[$memo['uid']] = $memo['desc']; } return array('note_uid' => array('type' => 'enum', 'name' => _("Show this note"), 'values' => $notes)); }
/** * Ensure the share system has a default notepad share for the current user * if the default share feature is activated. * * @return string|NULL The id of the new default share or NULL if no share * was created. */ public function ensureDefaultShare() { /* If the user doesn't own a notepad, create one. */ if (!empty($this->_params['auto_create']) && $this->_user && !count(Mnemo::listNotepads(true))) { $share = $this->_shares->newShare($this->_user, strval(new Horde_Support_Randomid()), $this->_getDefaultShareName()); $this->_prepareDefaultShare($share); $this->_shares->addShare($share); return $share->getName(); } }
$note = $storage->getByUID($uid, $passphrase); } catch (Mnemo_Exception $e) { Horde::url('list.php', true)->redirect(); } $note_id = $note['memo_id']; $notelist_id = $note['memolist_id']; } else { /* If we aren't provided with a memo and memolist, redirect to * list.php. */ $note_id = Horde_Util::getFormData('note'); $notelist_id = Horde_Util::getFormData('notepad'); if (!isset($note_id) || !$notelist_id) { Horde::url('list.php', true)->redirect(); } /* Get the current memo. */ $note = Mnemo::getMemo($notelist_id, $note_id, $passphrase); } try { $share = $GLOBALS['mnemo_shares']->getShare($notelist_id); } catch (Horde_Share_Exception $e) { $notification->push(sprintf(_("There was an error viewing this notepad: %s"), $e->getMessage()), 'horde.error'); Horde::url('list.php', true)->redirect(); } if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ)) { $notification->push(_("You do not have permission to view this notepad."), 'horde.error'); Horde::url('list.php', true)->redirect(); } /* If the requested note doesn't exist, display an error message. */ if (!$note || !isset($note['memo_id'])) { $notification->push(_("Note not found."), 'horde.error'); Horde::url('list.php', true)->redirect();
} catch (Horde_Exception $e) { if ($data) { $notification->push($e, 'horde.error'); $next_step = $data->cleanup(); } else { $notification->push(_("This file format is not supported."), 'horde.error'); $next_step = Horde_Data::IMPORT_FILE; } } } /* We have a final result set. */ if (is_array($next_step)) { /* Create a Mnemo storage instance. */ $memo_storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create($storage->get('target')); $max_memos = $GLOBALS['injector']->getInstance('Horde_Core_Perms')->hasAppPermission('max_notes'); $num_memos = Mnemo::countMemos(); foreach ($next_step as $row) { if ($max_memos !== true && $num_memos >= $max_memos) { Horde::permissionDeniedError('mnemo', 'max_notes', sprintf(_("You are not allowed to create more than %d notes."), $GLOBALS['injector']->getInstance('Horde_Core_Perms')->hasAppPermission('max_notes'))); break; } /* Check if we need to convert from iCalendar data into an array. */ if ($row instanceof Horde_Icalendar_vnote) { $row = $storage->fromiCalendar($row); } foreach ($app_fields as $field => $null) { if (!isset($row[$field])) { $row[$field] = ''; } } /* Default the tags if there isn't one. */
$view->url = Horde::url('memo.php'); if (!$view->modify || !$view->passphrase) { $injector->getInstance('Horde_Core_Factory_Imple')->create('Mnemo_Ajax_Imple_TagAutoCompleter', array('id' => 'memo_tags')); $view->body = $memo_body; $view->count = sprintf(_("%s characters"), '<span id="mnemo-count">' . Horde_String::length(str_replace(array("\r", "\n"), '', $memo_body)) . '</span>'); $view->encrypted = $memo_encrypted; $view->encryption = $storage->encryptionSupported(); try { $view->help = Horde::callHook('description_help', array(), 'mnemo', ''); } catch (Horde_Exception_HookNotSet $e) { } $view->loadingImg = Horde::img('loading.gif', _("Loading...")); $view->notepads = array(); if (!$prefs->isLocked('default_notepad')) { foreach (Mnemo::listNotepads(false, Horde_Perms::SHOW) as $id => $notepad) { if (!$notepad->hasPermission($user, Horde_Perms::EDIT)) { continue; } $view->notepads[] = array('id' => $id, 'selected' => $id == $memolist_id, 'label' => Mnemo::getLabel($notepad)); } } $view->tags = implode(', ', $memo_tags); if ($memo_id && $mnemo_shares->getShare($memolist_id)->hasPermission($user, Horde_Perms::DELETE)) { $view->delete = Horde::url('memo.php')->add(array('memo' => $memo_id, 'memolist' => $memolist_id, 'actionID' => 'delete_memos')); } } $page_output->addScriptFile('memo.js'); $page_output->header(array('title' => $title)); $notification->notify(); echo $view->render('memo/memo'); $page_output->footer();
$view->headers[] = array('id' => 's' . MNEMO::SORT_MOD_DATE, 'sorted' => $sortby == Mnemo::SORT_MOD_DATE, 'width' => '2%', 'label' => Horde::widget(array('url' => $baseurl->add('sortby', MNEMO::SORT_MOD_DATE), 'class' => 'sortlink', 'title' => _("Date")))); foreach ($memos as $memo_id => &$memo) { try { $share = $mnemo_shares->getShare($memo['memolist_id']); } catch (Horde_Share_Exception $e) { $notification->push($e); continue; } if ($view->showNotepad) { $memo['notepad'] = Mnemo::getLabel($share); } if ($share->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $label = sprintf(_("Edit \"%s\""), $memo['desc']); $memo['edit'] = Horde::url('memo.php')->add(array('memo' => $memo['memo_id'], 'memolist' => $memo['memolist_id'], 'actionID' => 'modify_memo'))->link(array('title' => $label)) . Horde::img('edit.png', $label, '') . '</a>'; } $memo['link'] = Horde::linkTooltip(Horde::url('view.php')->add(array('memo' => $memo['memo_id'], 'memolist' => $memo['memolist_id'])), '', '', '', '', $memo['body'] != $memo['desc'] ? Mnemo::getNotePreview($memo) : '') . (strlen($memo['desc']) ? htmlspecialchars($memo['desc']) : '<em>' . _("Empty Note") . '</em>') . '</a>'; // Get memo's most recent modification date or, if nonexistent, // the creation (add) date if (isset($memo['modified'])) { $modified = $memo['modified']; } elseif (isset($memo['created'])) { $modified = $memo['created']; } else { $modified = null; } if ($modified) { $memo['modifiedStamp'] = $modified->timestamp(); $memo['modifiedString'] = $modified->strftime($prefs->getValue('date_format')); } else { $memo['modifiedStamp'] = $memo['modifiedString'] = ''; }
$_prefs['sync_notepads'] = array('value' => 'a:0:{}', 'type' => 'multienum', 'enum' => array(), 'desc' => _("Select the notepads that, in addition to the default, should be used for synchronization with external devices:"), 'on_init' => function ($ui) { $enum = array(); $sync = @unserialize($GLOBALS['prefs']->getValue('sync_notepads')); if (empty($sync)) { $GLOBALS['prefs']->setValue('sync_notepads', serialize(array(Mnemo::getDefaultNotepad(Horde_Perms::DELETE)))); } foreach (Mnemo::listNotepads(false, Horde_Perms::DELETE) as $key => $list) { if ($list->getName() != Mnemo::getDefaultNotepad(Horde_Perms::DELETE)) { $enum[$key] = Mnemo::getLabel($list); } } $ui->prefs['sync_notepads']['enum'] = $enum; }, 'on_change' => function () { $sync = @unserialize($GLOBALS['prefs']->getValue('sync_notepads')); $haveDefault = false; $default = Mnemo::getDefaultNotepad(Horde_Perms::DELETE); foreach ($sync as $cid) { if ($cid == $default) { $haveDefault = true; break; } } if (!$haveDefault) { $sync[] = $default; $GLOBALS['prefs']->setValue('sync_notepads', serialize($sync)); } if ($GLOBALS['conf']['activesync']['enabled'] && !$GLOBALS['prefs']->getValue('activesync_no_multiplex')) { try { $sm = $GLOBALS['injector']->getInstance('Horde_ActiveSyncState'); $sm->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger')); $devices = $sm->listDevices($GLOBALS['registry']->getAuth());
/** * Retrieve the UID for the current user's default notepad. * * @return string UID. * @since 4.2.0 */ public function getDefaultShare() { return Mnemo::getDefaultNotepad(Horde_Perms::EDIT); }
/** * Build a note based on data array * * @param array $note The data for the note * @param string $passphrase A passphrase for decrypting a note * * @return array The converted data array representing the note */ protected function _buildNote($note, $passphrase = null) { $encrypted = false; $body = $note['body']; $id = Horde_Url::uriB64Encode($note['uid']); if (strpos($body, '-----BEGIN PGP MESSAGE-----') === 0) { $encrypted = true; if (empty($passphrase)) { $passphrase = Mnemo::getPassphrase($id); } if (empty($passphrase)) { $body = new Mnemo_Exception(_("This note has been encrypted."), Mnemo::ERR_NO_PASSPHRASE); } else { try { $body = $this->_decrypt($body, $passphrase)->message; } catch (Mnemo_Exception $e) { $body = $e; } Mnemo::storePassphrase($id, $passphrase); } } $tagger = $GLOBALS['injector']->getInstance('Mnemo_Tagger'); $tags = $tagger->getTags($note['uid'], 'note'); if (!empty($note['categories'])) { usort($tags, 'strcoll'); if (array_diff($note['categories'], $tags)) { $tagger->replaceTags($note['uid'], $note['categories'], $GLOBALS['registry']->getAuth(), 'note'); } $tags = $note['categories']; } $result = array('memolist_id' => $this->_notepad, 'memo_id' => $id, 'uid' => $note['uid'], 'tags' => $tags, 'desc' => $note['summary'], 'encrypted' => $encrypted, 'body' => $body); if (!empty($note['creation-date'])) { $result['created'] = new Horde_Date($note['creation-date']); } if (!empty($note['last-modification-date'])) { $result['modified'] = new Horde_Date($note['last-modification-date']); } return $result; }
/** * Load the full, sorted task list. */ protected function _loadNotes() { global $prefs; $this->_notes = Mnemo::listMemos($prefs->getValue('sortby'), $prefs->getValue('sortdir')); }
if (count($search_results) == 1) { $note = array_shift($search_results); Horde::url('view.php', true)->add(array('memo' => $note['memo_id'], 'memolist' => $note['memolist_id']))->redirect(); } $memos = $search_results; $page_output->addScriptFile('tables.js', 'horde'); $page_output->addScriptFile('quickfinder.js', 'horde'); $page_output->header(array('title' => _("Search Results"))); require MNEMO_TEMPLATES . '/list/header.inc'; if (count($memos)) { $sortby = $prefs->getValue('sortby'); $sortdir = $prefs->getValue('sortdir'); $showNotepad = $prefs->getValue('show_notepad'); $baseurl = 'list.php'; require MNEMO_TEMPLATES . '/list/memo_headers.inc'; foreach ($memos as $memo_id => $memo) { $viewurl = Horde::url('view.php')->add(array('memo' => $memo['memo_id'], 'memolist' => $memo['memolist_id'])); $memourl = Horde::url('memo.php')->add(array('memo' => $memo['memo_id'], 'memolist' => $memo['memolist_id'])); try { $share = $GLOBALS['mnemo_shares']->getShare($memo['memolist_id']); $notepad = Mnemo::getLabel($share); } catch (Horde_Share_Exception $e) { $notepad = $memo['memolist_id']; } require MNEMO_TEMPLATES . '/list/memo_summaries.inc'; } require MNEMO_TEMPLATES . '/list/memo_footers.inc'; } else { require MNEMO_TEMPLATES . '/list/empty.inc'; } $page_output->footer();
/** * @throws Mnemo_Exception */ public function download(Horde_Variables $vars) { global $injector, $registry; switch ($vars->actionID) { case 'export': /* Get the full, sorted memo list. */ $notes = Mnemo::listMemos(); switch ($vars->exportID) { case Horde_Data::EXPORT_CSV: $data = array(); foreach ($notes as $note) { unset($note['desc'], $note['memo_id'], $note['memolist_id'], $nore['uid']); $note['tags'] = implode(',', $note['tags']); if ($note['body'] instanceof Mnemo_Exception) { $note['body'] = $note['body']->getMessage(); } $data[] = $note; } $injector->getInstance('Horde_Core_Factory_Data')->create('Csv', array('cleanup' => array($this, 'cleanupData')))->exportFile(_("notes.csv"), $data, true); exit; } } }
$_prefs['sync_notepads'] = array('value' => 'a:0:{}', 'type' => 'multienum', 'enum' => array(), 'desc' => _("Select the notepads that, in addition to the default, should be used for synchronization with external devices:"), 'on_init' => function ($ui) { $enum = array(); $sync = @unserialize($GLOBALS['prefs']->getValue('sync_notepads')); if (empty($sync)) { $GLOBALS['prefs']->setValue('sync_notepads', serialize(array(Mnemo::getDefaultNotepad()))); } foreach (Mnemo::listNotepads(false, Horde_Perms::EDIT) as $key => $list) { if ($list->getName() != Mnemo::getDefaultNotepad(Horde_Perms::EDIT)) { $enum[$key] = Mnemo::getLabel($list); } } $ui->prefs['sync_notepads']['enum'] = $enum; }, 'on_change' => function () { $sync = @unserialize($GLOBALS['prefs']->getValue('sync_notepads')); $haveDefault = false; $default = Mnemo::getDefaultNotepad(Horde_Perms::EDIT); foreach ($sync as $cid) { if ($cid == $default) { $haveDefault = true; break; } } if (!$haveDefault) { $sync[] = $default; $GLOBALS['prefs']->setValue('sync_notepads', serialize($sync)); } if ($GLOBALS['conf']['activesync']['enabled'] && !$GLOBALS['prefs']->getValue('activesync_no_multiplex')) { try { $sm = $GLOBALS['injector']->getInstance('Horde_ActiveSyncState'); $sm->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger')); $devices = $sm->listDevices($GLOBALS['registry']->getAuth());
/** * * @param array $row Hash of the note data, db keys. * @param string $passphrase The encryption passphrase. * * @return array a Task hash. * @throws Mnemo_Exception */ protected function _buildNote($row, $passphrase = null) { // Make sure notes always have a UID. if (empty($row['memo_uid'])) { $row['memo_uid'] = strval(new Horde_Support_Guid()); $query = 'UPDATE ' . $this->_table . ' SET memo_uid = ?' . ' WHERE memo_owner = ? AND memo_id = ?'; $values = array($row['memo_uid'], $row['memo_owner'], $row['memo_id']); try { $this->_db->update($query, $values); } catch (Horde_Db_Exception $e) { throw new Mnemo_Exception($e->getMessage()); } } // Decrypt note if requested. $encrypted = false; $body = $this->_column->binaryToString($row['memo_body']); $body = Horde_String::convertCharset($body, $this->_charset, 'UTF-8'); if (strpos($body, '-----BEGIN PGP MESSAGE-----') === 0) { $encrypted = true; if (empty($passphrase)) { $passphrase = Mnemo::getPassphrase($row['memo_id']); } if (empty($passphrase)) { $body = new Mnemo_Exception(_("This note has been encrypted."), Mnemo::ERR_NO_PASSPHRASE); } else { try { $body = $this->_decrypt($body, $passphrase); $body = $body->message; } catch (Mnemo_Exception $e) { $body = $e; } Mnemo::storePassphrase($row['memo_id'], $passphrase); } } // Create a new note based on $row's values. $uid = Horde_String::convertCharset($row['memo_uid'], $this->_charset, 'UTF-8'); $memo = array('memolist_id' => $row['memo_owner'], 'memo_id' => $row['memo_id'], 'uid' => $uid, 'desc' => Horde_String::convertCharset($row['memo_desc'], $this->_charset, 'UTF-8'), 'body' => $body, 'tags' => $GLOBALS['injector']->getInstance('Mnemo_Tagger')->getTags($uid, 'note'), 'encrypted' => $encrypted); try { $userId = $GLOBALS['registry']->getAuth(); $log = $GLOBALS['injector']->getInstance('Horde_History')->getHistory('mnemo:' . $row['memo_owner'] . ':' . $row['memo_uid']); foreach ($log as $entry) { switch ($entry['action']) { case 'add': $memo['created'] = new Horde_Date($entry['ts']); if ($userId != $entry['who']) { $memo['createdby'] = sprintf(_("by %s"), Mnemo::getUserName($entry['who'])); } else { $memo['createdby'] = _("by me"); } break; case 'modify': $memo['modified'] = new Horde_Date($entry['ts']); if ($userId != $entry['who']) { $memo['modifiedby'] = sprintf(_("by %s"), Mnemo::getUserName($entry['who'])); } else { $memo['modifiedby'] = _("by me"); } break; } } } catch (Horde_Exception $e) { } return $memo; }
public function testDefaultShareDeletePermission() { $GLOBALS['conf']['share']['auto_create'] = true; Mnemo::initialize(); $shares = $GLOBALS['mnemo_shares']->listShares('*****@*****.**'); $default = array_pop($shares); $this->assertTrue($default->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)); }
/** * Modifies an existing note. * * @param string $noteId The note to modify. * @param string $desc The first line of the note. * @param string $body The whole note body. * @param string $tags The tags of the note. * @param string $passphrase The passphrase to encrypt the note with. * * @throws Mnemo_Exception */ public function modify($noteId, $desc, $body, $tags = '', $passphrase = null) { if ($passphrase) { $body = $this->_encrypt($body, $passphrase); Mnemo::storePassphrase($noteId, $passphrase); } $uid = $this->_modify($noteId, $desc, $body, $tags); // Update tags. $GLOBALS['injector']->getInstance('Mnemo_Tagger')->replaceTags($uid, $tags, $GLOBALS['registry']->getAuth(), 'note'); // Log the modification of this item in the history log. if ($uid) { try { $GLOBALS['injector']->getInstance('Horde_History')->log('mnemo:' . $this->_notepad . ':' . $uid, array('action' => 'modify'), true); } catch (Horde_Exception $e) { } } }
$memo = $storage->getByUID($uid, $passphrase); } catch (Mnemo_Exception $e) { Horde::url('list.php', true)->redirect(); } $memo_id = $memo['memo_id']; $memolist_id = $memo['memolist_id']; } else { /* If we aren't provided with a memo and memolist, redirect to * list.php. */ $memo_id = Horde_Util::getFormData('memo'); $memolist_id = Horde_Util::getFormData('memolist'); if (!isset($memo_id) || !$memolist_id) { Horde::url('list.php', true)->redirect(); } /* Get the current memo. */ $memo = Mnemo::getMemo($memolist_id, $memo_id, $passphrase); } try { $share = $GLOBALS['mnemo_shares']->getShare($memolist_id); } catch (Horde_Share_Exception $e) { $notification->push(sprintf(_("There was an error viewing this notepad: %s"), $e->getMessage()), 'horde.error'); Horde::url('list.php', true)->redirect(); } if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ)) { $notification->push(_("You do not have permission to view this notepad."), 'horde.error'); Horde::url('list.php', true)->redirect(); } /* If the requested note doesn't exist, display an error message. */ if (!$memo || !isset($memo['memo_id'])) { $notification->push(_("Note not found."), 'horde.error'); Horde::url('list.php', true)->redirect();