,
Request #5936).
--------
v2.2-RC1
--------
[jan] Implement WebDAV DELETE.
[cjh] Add quick links to the sidebar block for adding notes to a specific
notepad (Gunnar Wrobel , Request #5716).
[cjh] Fix generation of UIDs with PHP 5.2+.
----------
v2.2-ALPHA
----------
[cjh] Show tooltips in the summary block, and restrict tooltips to 20 lines
(Request #3443).
[cjh] Optionally show a note's notepad in the list view (Request #2317).
[cjh] Add quick (inline) note searching.
[cjh] Add the ability to save a note as a PDF.
[jan] Add support for encrypted notes.
[cjh] Move notepad selection/deselection to a collapsible panel.
[mas] Conform to WCAG 1.0 Priority 2/Section 508 accessibility guidelines.
(Request #4080)
[cjh] Notes search should be either title or full text (Request #4277).
[cjh] Make the note edit view the full page width.
------
v2.1.2
------
[jan] SECURITY: Fix privilege escalation in Horde API.
[cjh] SECURITY: Fix missing ownership validation on share changes.
------
v2.1.1
------
[jan] Show error message if imported file didn't contain notes.
[jan] Add Slovenian translation (Duck ).
[jan] Add categories from imported contacts to the user's categories.
[jan] Show personal notepad by default with disabled preferences (Bug #4078).
----
v2.1
----
[jan] Fix portal block if used with Kolab driver (tokoe@kde.org, Bug #2735).
[jan] Add Russian translation (Alexey Zakharov ).
[ben] Better support for MS-SQL.
--------
v2.1-RC1
--------
[jan] Confirm note deletions (Request #1156).
[jan] Add CLI script to import vNote data.
[cjh] Add support for dynamic re-sorting of the note list, including saving
the sort preferences on any changes.
[jan] Show character count next to notes.
[mas] Change any output of and tags to and for better
accessibility support.
[jan] Add permissions to restrict number of notes.
------
v2.0.3
------
[cjh] Close several XSS vulnerabilities with note and notepad data.
------
v2.0.2
------
[jan] Allow to import more than one note from vNote data at once.
----------
v2.0.2-RC1
----------
[cjh] Fix resetting categories to Unfiled (Bug #2018).
[cjh] Use bind variables in SQL driver, clean up required parameters
(selsky@columbia.edu, Bug #1791).
[cjh] Add a PostgreSQL upgrade script (Bug #1779).
[cjh] Better error handling when deleting shares that don't exist (Bug #1754).
[jan] Add Japanese translation (Hiromi Kimura ).
[jan] Add shortcut icon (favicon.ico).
------
v2.0.1
------
[jan] Fix print view.
[jan] Fix print button.
----
v2.0
----
[cjh] UIDs need to be stored in the History system with a mnemo: prefix and
with the notepad so as not to confuse different instances of the
same note (if two users both have a note on their seperate notepads,
they should have unique histories for that note).
[cjh] Don't throw a fatal error if an empty share name is submitted
(Bug #1000).
--------
v2.0-RC3
--------
[cjh] Add My Notepads menu entry.
--------
v2.0-RC2
--------
[jan] Add Czech translation (Pavel Chytil ).
[jan] Add Latvian translation (Janis Eisaks ).
--------
v2.0-RC1
--------
[jan] Tweak layout of the summary block.
---------
v2.0-BETA
---------
[jan] Add Polish translation (Mateusz Kaminski ).
[jan] Add special black-on-white styles for message printing.
[jan] Add access keys.
[cjh] Add Kolab drivers (Stuart Bingë ).
----------
v2.0-ALPHA
----------
[cjh] GUIDs now only contain mnemo: and the note ID - sharename is not needed.
[cjh] Note IDs are now 32-character unique strings, to be useable as GUIDs.
The SQL table definition has changed; conversion scripts are in scripts/.
[cjh] The notes/ API now implements the modern methods required for SyncML and
other syncing efforts.
[cjh] Make sure there is a view link for empty notes.
[cjh] Add a Delete link from the note edit screen.
[cjh] Make sure that the correct categories for a note's current notepad
are always used.
[cjh] Change how memos are stored in the SQL driver.
scripts/create_sequence.php will update an existing database with no
loss of data.
[cjh] Display the Creation and Last-Modified dates in the note view.
[cjh] Track addition, modification, and deletion of notes
with the Horde History:: API.
[cjh] Add import of vNotes.
[cjh] Show the full memo body in a tooltip.
[cjh] Add a preference for the default category for notes
(Brian Keifer ).
[jan] Add UTF-8 support and charset parameter for backend drivers.
[jan] Only show selected note categories on the summary screen
(Brian Keifer ).
[cjh] Much more comprehensive permissions checking, and support for
guest access.
[cjh] Use the global shares editing page for changing/assigning share
permissions.
[mac] Allow importing onto any available Notepad.
[mac] Add shared notepads.
------
v1.1.4
------
[jan] Close XSS when setting the parent frame's page title by javascript (cjh).
------
v1.1.3
------
[jan] Add Polish translation (Mateusz Kaminski ).
------
v1.1.2
------
[jan] Make memos without description accessible from the memo list.
------
v1.1.1
------
[jan] Add Italian translation (Sergio G. Caredda ).
[jan] Add Romanian translation (Eugen Hoanca ,
Marius Dragulescu ).
----
v1.1
----
[jan] Rename Memos to Notes (mac).
[jan] Add print memo button (mac).
[jan] Show current category color in category color options screen
(Jan Kuipers ).
[jan] Add ability to create/remove categories (mac).
[jan] Add user preferences for the color of different categories (mac).
[jan] Add Mnemo::addParameter().
[jan] Add Greek translation (Stefanos I. Dimitriou ).
[jan] Add Slovak translation (Ivan Noris ).
[jan] Add Norwegian Bokmaal translation (Torstein S. Hansen ).
[jan] Add Bulgarian translation (Miroslav Pendev ).
[jan] Add Lithuanian translation (Darius Matuliauskas ).
[jan] Replace = with ).
----
v1.0
----
[jan] Add Hungarian translation (Laszlo L. Tornoci ).
[jan] Add Simplified Chinese translation (Peter Wang ).
[jan] Add Czech translation (Pavel Chytil ).
[jan] Add Brazilian Portuguese translation (Antonio Dias ).
[jan] Add Dutch translation (Jan Kuipers ).
[jan] Add French translation (Thierry Thomas ).
[jan] Add Finnish translation (Leena Heino ).
[jan] Add Norwegian Nynorsk translation (Per-Stian Vatne ).
[jan] Add Traditional Chinese translation (Chih-Wei Yeh ).
[jan] Add Swedish translation (Andreas Dahlén ).
[jan] Add Spanish translation (Raul Alvarez Venegas ).
[jan] Add German translation.
[jan] Add Portuguese translation (Nuno Loureiro ).
[cjh] Initial Mnemo version, based on Nag.
mnemo-4.1.2/docs/CREDITS 0000664 0001750 0001750 00000010400 12233763566 012715 0 ustar jan jan ========================
Mnemo Development Team
========================
Core Developers
===============
- Chuck Hagenbuch
- Jan Schneider
Localization
============
===================== ======================================================
Basque Euskal Herriko Unibertsitatea
Brazilian Portuguese Antonio Dias
Fabio Gomes
Luis Felipe Marzagao
Eduardo de Carli
Bulgarian Miroslav Pendev
Chinese (Simplified) Peter Wang
Anna Chen
Chinese (Traditional) Chih-Wei Yeh
Croatian Matej Vela
Czech Pavel Chytil
Danish Martin List-Petersen
Brian Truelsen
Niels Baggesen
Dutch Jan Kuipers
Finnish Leena Heino
French Thierry Thomas
Patrick Abiven
Vincent Vinet
Yannick Sebastia
Laurent Foucher
Paul De Vlieger
German Jan Schneider
Greek Stefanos I. Dimitriou
Silligardos Xristoforos
Anagnostopoulos Apostolis
Konstantinos C. Milosis
Hungarian Laszlo L. Tornoci
Andras Galos
Zoltán Németh
Italian Sergio G. Caredda
Marko Djukic
Marco Pirovano
Cristian Manoni
Massimo Malabotta
Japanese Hiromi Kimura
Latvian Janis Eisaks
Lithuanian Darius Matuliauskas
Vilius Šumskas
Norwegian Bokmaal Torstein S. Hansen
Norwegian Nynorsk Per-Stian Vatne
Polish Mateusz Kaminski
Piotr Tarnowski
Krzysztof Kozera
Portuguese Nuno Loureiro
Manuel Menezes de Sequeira
Romanian Eugen Hoanca
Marius Dragulescu
Russian Alexey Zakharov
Slovak Ivan Noris
Martin Matuška
Jozef Sudolský
Slovenian Duck
Spanish Raul Alvarez Venegas
Manuel Perez Ayala
Juan C. Blanco
Swedish Andreas Dahlén
Joaquim Homrighausen
Per Olof Ljungmark
Turkish Istanbul Technical University IT Department
Middle East Technical University
Ukrainian Andriy Kopystyansky
===================== ======================================================
mnemo-4.1.2/docs/INSTALL 0000664 0001750 0001750 00000013170 12233763566 012735 0 ustar jan jan =====================
Installing Mnemo H5
=====================
This document contains instructions for installing the Mnemo web-based notes
application on your system.
For information on the capabilities and features of Mnemo, see the file
README_ in the top-level directory of the Mnemo distribution.
Prerequisites
=============
To function properly, Mnemo **requires** the following:
1. A working Horde installation.
Mnemo runs within the `Horde Application Framework`_, a set of common tools
for web applications written in PHP. You must install Horde before
installing Mnemo.
.. Important:: Mnemo H5 requires version 5.0+ of the Horde Framework -
earlier versions of Horde will **not** work.
.. Important:: Be sure to have completed all of the steps in the
`horde/docs/INSTALL`_ file for the Horde Framework before
installing Mnemo. Many of Mnemo's prerequisites are also
Horde prerequisites. Additionally, many of Mnemo's optional
features are configured via the Horde install.
.. _`Horde Application Framework`: http://www.horde.org/apps/horde
2. SQL support in PHP *or* a configured Kolab Server.
Mnemo will store its data in either an SQL database or on a Kolab Server.
If you use SQL, build PHP with whichever SQL driver you require; see the
Horde INSTALL_ file for details.
Installing Mnemo
================
The **RECOMMENDED** way to install Mnemo is using the PEAR installer.
Alternatively, if you want to run the latest development code or get the
latest not yet released fixes, you can install Mnemo from Git.
Installing with PEAR
~~~~~~~~~~~~~~~~~~~~
First follow the instructions in `horde/docs/INSTALL`_ to prepare a PEAR
environment for Horde and install the Horde Framework.
When installing Mnemo through PEAR now, the installer will automatically
install any dependencies of Mnemo too. If you want to install Mnemo with all
optional dependencies, but without the binary PECL packages that need to be
compiled, specify both the ``-a`` and the ``-B`` flag::
pear install -a -B horde/mnemo
By default, only the required dependencies will be installed::
pear install horde/mnemo
If you want to install Mnemo even with all binary dependencies, you need to
remove the ``-B`` flag. Please note that this might also try to install PHP
extensions through PECL that might need further configuration or activation in
your PHP configuration::
pear install -a horde/mnemo
Installing from Git
~~~~~~~~~~~~~~~~~~~
See http://www.horde.org/source/git.php
Configuring Mnemo
=================
1. Configuring Horde for Mnemo
Mnemo requires a permanent ``Shares`` backend in Horde to manage notepads
and to add notes to notepads. If you didn't setup a Share backend yet, go
to the configuration interface, select Horde from the list of applications
and select the ``Shares`` tab. Unless you are using Kolab, you should select
``SQL``.
2. Configuring Mnemo
You must login to Horde as a Horde Administrator to finish the
configuration of Mnemo. Use the Horde ``Administration`` menu item to get
to the administration page, and then click on the ``Configuration`` icon to
get the configuration page. Select ``Notes`` from the selection list of
applications. Fill in or change any configuration values as needed. When
done click on ``Generate Notes Configuration`` to generate the ``conf.php``
file. If your web server doesn't have write permissions to the Mnemo
configuration directory or file, it will not be able to write the file. In
this case, go back to ``Configuration`` and choose one of the other methods
to create the configuration file ``mnemo/config/conf.php``.
Documentation on the format and purpose of the other configuration files in
the ``config/`` directory can be found in each file. You may create
``*.local.php`` versions of these files if you wish to customize Mnemo's
appearance and behavior. See the header of the configuration files for
details and examples. The defaults will be correct for most sites.
3. Creating the database table
Once you finished the configuration in the previous step, you can create all
database tables by clicking the ``DB schema is out of date.`` link in the
Mnemo row of the configuration screen.
Alternatively you creating the Mnemo database tables can be accomplished with
horde's ``horde-db-migrate`` utility. If your database is properly setup in
the Horde configuration, just run the following::
horde/bin/horde-db-migrate mnemo
4. Testing Mnemo
Use Mnemo to create, modify, and delete notes. Test at least the following:
- Creating a new note
- Modifying a note
- Deleting a note
Obtaining Support
=================
If you encounter problems with Mnemo, help is available!
The Horde Frequently Asked Questions List (FAQ), available on the Web at
http://wiki.horde.org/FAQ
The Horde Project runs a number of mailing lists, for individual applications
and for issues relating to the project as a whole. Information, archives, and
subscription information can be found at
http://www.horde.org/community/mail
Lastly, Horde developers, contributors and users may also be found on IRC,
on the channel #horde on the Freenode Network (irc.freenode.net).
Please keep in mind that Mnemo is free software written by volunteers. For
information on reasonable support expectations, please read
http://www.horde.org/community/support
Thanks for using Mnemo!
The Horde team
.. _README: README
.. _INSTALL:
.. _`horde/docs/INSTALL`: ../../horde/docs/INSTALL
.. _`horde/docs/TRANSLATIONS`: ../../horde/docs/TRANSLATIONS
mnemo-4.1.2/docs/RELEASE_NOTES 0000664 0001750 0001750 00000003336 12233763566 013662 0 ustar jan jan notes['fm']['focus'] = array(Horde_Release::FOCUS_MINORSECURITY, Horde_Release::FOCUS_MINORBUG);
/* Mailing list release notes. */
$this->notes['ml']['changes'] = <<notes['fm']['changes'] = <<notes['name'] = 'Mnemo';
$this->notes['list'] = 'horde';
$this->notes['fm']['project'] = 'mnemo';
$this->notes['fm']['branch'] = 'Horde 5';
mnemo-4.1.2/docs/TODO 0000664 0001750 0001750 00000000310 12233763566 012364 0 ustar jan jan =============================
Mnemo Development TODO List
=============================
:Contact: horde@lists.horde.org
- Allow resorting search results.
- Next/Previous buttons in the note view.
mnemo-4.1.2/docs/UPGRADING 0000664 0001750 0001750 00000004657 12233763566 013161 0 ustar jan jan =================
Upgrading Mnemo
=================
:Contact: horde@lists.horde.org
.. contents:: Contents
.. section-numbering::
General instructions
====================
These are instructions to upgrade from earlier Mnemo versions. Please backup
your existing data before running any of the steps described below. You can't
use the updated data with your old Mnemo version anymore.
Upgrading Mnemo is as easy as running::
pear upgrade -a -B horde/mnemo
If you want to upgrade from a Mnemo version prior to 3.0, please
follow the instructions in INSTALL_ to install the most recent Mnemo
version using the PEAR installer.
After updating to a newer Mnemo version, you **always** need to update
configurations and database schemes. Log in as an administrator, go to
Administration => Configuration and update anything that's highlighted as
outdated.
Upgrading Mnemo from 2.2.1 to 2.2.2
===================================
The group_uid field in the SQL share driver groups table has been changed from
an INT to a VARCHAR(255). Execute the provided SQL script to update your
database if you are using the native SQL share driver.
mysql --user=root --password= < scripts/upgrades/2.2.1_to_2.2.2.sql
Upgrading Mnemo from 2.2 to 2.2.1
=================================
The share_owner field in the SQL share driver table has been changed from a
VARCHAR(32) to a VARCHAR(255). Execute the provided SQL script to update your
database if you are using the native SQL share driver.
mysql --user=root --password= < scripts/upgrades/2.2_to_2.2.1.sql
Upgrading Mnemo from 2.x to 2.2
===============================
New Beta SQL Share Driver Support
---------------------------------
A new beta-level SQL Horde_Share driver has been added in Horde 3.2. This driver
offers significant performance improvements over the existing Datatree driver,
but it has not received the same level of testing, thus the beta designation.
In order to make use of this driver, you must be using Horde 3.2-RC3 or
later. To create the new tables needed for this driver, execute the provided SQL
script::
mysql --user=root --password= < scripts/upgrades/2.1_to_2.2.sql
If you want to use the new SQL Share driver, you must also execute the
provided PHP script to migrate your existing share data to the new format::
mnemo-convert-datatree-shares-to-sql
.. _INSTALL: INSTALL
mnemo-4.1.2/lib/Ajax/Imple/EditNote.php 0000664 0001750 0001750 00000002343 12233763566 015677 0 ustar jan jan
* @category Horde
* @package Mnemo
*/
class Mnemo_Ajax_Imple_EditNote extends Horde_Core_Ajax_Imple_InPlaceEditor
{
/**
*/
protected function _handleEdit(Horde_Variables $vars)
{
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create();
$memo = $storage->getByUID($vars->id);
/* Are we requesting the unformatted text? */
if ($vars->action == 'load') {
return $memo['body'];
}
$share = $GLOBALS['mnemo_shares']->getShare($memo['memolist_id']);
if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) {
throw new Horde_Exception_PermissionDenied(_("You do not have permission to edit this note."));
}
$storage->modify($memo['memo_id'], $memo['desc'], $vars->{$vars->input});
return $GLOBALS['injector']->getInstance('Horde_Core_Factory_TextFilter')->filter(
$vars->{$vars->input},
'text2html',
array('parselevel' => Horde_Text_Filter_Text2html::MICRO)
);
}
}
mnemo-4.1.2/lib/Ajax/Application.php 0000664 0001750 0001750 00000001240 12233763566 015354 0 ustar jan jan
* @category Horde
* @license http://www.horde.org/licenses/apache ASL
* @package Mnemo
*/
class Mnemo_Ajax_Application extends Horde_Core_Ajax_Application
{
/**
*/
protected function _init()
{
$this->addHandler('Horde_Core_Ajax_Application_Handler_Imple');
$this->addHandler('Horde_Core_Ajax_Application_Handler_Prefs');
}
}
mnemo-4.1.2/lib/Block/Note.php 0000664 0001750 0001750 00000006032 12233763566 014171 0 ustar jan jan
* @package Mnemo
*/
class Mnemo_Block_Note extends Horde_Core_Block
{
/**
*/
private $_notename = '';
/**
*/
public function __construct($app, $params = array())
{
parent::__construct($app, $params);
$this->_name = _("View note");
}
/**
*/
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,
)
);
}
/**
*/
protected function _title()
{
return htmlspecialchars($this->_getTitle());
}
/**
*/
protected function _content()
{
$memo = $this->_getNote();
$html = '';
$body = $GLOBALS['injector']
->getInstance('Horde_Core_Factory_TextFilter')
->filter(
$memo['body'],
'text2html',
array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
try {
$body = Horde::callHook('format_description', array($body), 'mnemo', $body);
} catch (Horde_Exception_HookNotSet $e) {}
$html .= $body . '
';
$GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')
->create('Mnemo_Ajax_Imple_EditNote', array(
'dataid' => $this->_params['note_uid'],
'id' => 'noteBody' . $memo['memo_id'],
'rows' => substr_count($memo['body'], "\n")));
return $html;
}
/**
*/
private function _getNote()
{
if (!isset($this->_params['note_uid'])) {
throw new Horde_Exception(_("No note loaded"));
}
$uid = $this->_params['note_uid'];
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create();
try {
$memo = $storage->getByUID($uid);
} catch (Mnemo_Exception $e) {
if (!empty($this->_notename)) {
$msg = sprintf(_("An error occurred displaying %s"), $this->_notename);
} else {
$msg = _("An error occurred displaying the note");
}
throw new Horde_Exception($msg);
}
return $memo;
}
/**
*/
private function _getTitle()
{
if (empty($this->_notename)) {
$note = $this->_getNote();
$this->_notename = $note['desc'];
}
return $this->_notename;
}
}
mnemo-4.1.2/lib/Block/Summary.php 0000664 0001750 0001750 00000007604 12233763566 014727 0 ustar jan jan _name = _("Notes Summary");
}
/**
*/
protected function _title()
{
global $registry;
$label = !empty($this->_params['block_title'])
? $this->_params['block_title']
: $registry->get('name');
return Horde::link(Horde::url($registry->getInitialPage(), true))
. htmlspecialchars($label) . '';
}
/**
*/
protected function _params()
{
$cManager = new Horde_Prefs_CategoryManager();
$categories = array();
foreach ($cManager->get() as $c) {
$categories[$c] = $c;
}
return array(
'show_actions' => array(
'type' => 'checkbox',
'name' => _("Show action buttons?"),
'default' => 1
),
'show_notepad' => array(
'type' => 'checkbox',
'name' => _("Show notepad name?"),
'default' => 1
),
'show_categories' => array(
'type' => 'multienum',
'name' => _("Show notes from these categories"),
'default' => array(),
'values' => $categories
)
);
}
/**
*/
protected function _content()
{
global $registry, $prefs;
$cManager = new Horde_Prefs_CategoryManager();
$colors = $cManager->colors();
$fgcolors = $cManager->fgColors();
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) {
if (!empty($this->_params['show_categories']) &&
!in_array($memo['category'], $this->_params['show_categories'])) {
continue;
}
$html .= '';
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 .= ''
. Horde::link(htmlspecialchars(Horde::url($editurl, true)->add('actionID', 'modify_memo')), _("Edit Note"))
. Horde::img($editImg, _("Edit Note"))
. ' | ';
}
if (!empty($this->_params['show_notepad'])) {
$html .= '' . htmlspecialchars(Mnemo::getLabel($shares->getShare($memo['memolist_id']))) . ' | ';
}
$viewurl = Horde::url('view.php')->add(
array('memo' => $memo['memo_id'],
'memolist' => $memo['memolist_id']));
$html .= ''
. Horde::linkTooltip(
htmlspecialchars(Horde::url($viewurl, true)),
'', '', '', '',
$memo['body'] != $memo['desc'] ? Mnemo::getNotePreview($memo) : '')
. (strlen($memo['desc']) ? htmlspecialchars($memo['desc']) : '' . _("Empty Note") . '')
. ' | '
. htmlspecialchars($memo['category'] ? $memo['category'] : _("Unfiled"))
. " |
\n";
}
if (!$memos) {
return '' . _("No notes to display") . '
';
}
return '';
}
}
mnemo-4.1.2/lib/Driver/Kolab.php 0000664 0001750 0001750 00000023344 12233763566 014522 0 ustar jan jan
* @author Thomas Jarosch
* @author Stuart Binge
* @since Mnemo 2.0
* @package Mnemo
*/
class Mnemo_Driver_Kolab extends Mnemo_Driver
{
/**
* The Kolab_Storage backend.
*
* @var Horde_Kolab_Storage
*/
private $_kolab;
/**
* The current notepad.
*
* @var Horde_Kolab_Storage_Data
*/
private $_data;
/**
* Construct a new Kolab storage object.
*
* @param string $notepad The name of the notepad to load/save notes from.
* @param array $params The connection parameters
*
* @throws InvalidArguementException
*/
public function __construct($notepad, $params = array())
{
if (empty($params['storage'])) {
throw new InvalidArgumentException('Missing required storage handler.');
}
$this->_notepad = $notepad;
$this->_kolab = $params['storage'];
}
/**
* Retrieves all of the notes of the current notepad from the backend.
*
* @throws Mnemo_Exception
*/
public function retrieve()
{
$this->_memos = array();
try {
$note_list = $this->_getData()->getObjects();
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
if (empty($note_list)) {
return;
}
foreach ($note_list as $note) {
$this->_memos[Horde_Url::uriB64Encode($note['uid'])] = $this->_buildNote($note);
}
}
/**
* Retrieves one note from the backend.
*
* @param string $noteId The ID of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The array of note attributes.
* @throws Mnemo_Exception
* @throws Horde_Exception_NotFound
*/
public function get($noteId, $passphrase = null)
{
try {
$uid = Horde_Url::uriB64Decode($noteId);
if ($this->_getData()->objectIdExists($uid)) {
$note = $this->_getData()->getObject($uid);
return $this->_buildNote($note, $passphrase);
} else {
throw new Horde_Exception_NotFound();
}
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
}
/**
* Retrieves one note from the backend by UID.
*
* @param string $uid The UID of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The array of note attributes.
* @throws Mnemo_Exception
* @throws Horde_Exception_NotFound
*/
public function getByUID($uid, $passphrase = null)
{
//@todo: search across notepads
return $this->get(Horde_Url::uriB64Encode($uid), $passphrase);
}
/**
* Adds a note to the backend storage.
*
* @param string $noteId The ID of the new note.
* @param string $desc The first line of the note.
* @param string $body The whole note body.
* @param string $category The category of the note.
*
* @return string The unique ID of the new note.
* @throws Mnemo_Exception
*/
protected function _add($noteId, $desc, $body, $category)
{
$uid = Horde_Url::uriB64Decode($noteId);
$object = array(
'uid' => $uid,
'summary' => $desc,
'body' => $body,
'categories' => array($category),
);
try {
$this->_getData()->create($object);
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
return $uid;
}
/**
* 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 $category The category of the note.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
protected function _modify($noteId, $desc, $body, $category)
{
$uid = Horde_Url::uriB64Decode($noteId);
try {
$this->_getData()->modify(
array(
'uid' => $uid,
'summary' => $desc,
'body' => $body,
'categories' => array($category),
)
);
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
return $uid;
}
/**
* Moves a note to a new notepad.
*
* @param string $noteId The note to move.
* @param string $newNotepad The new notepad.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
protected function _move($noteId, $newNotepad)
{
$uid = Horde_Url::uriB64Decode($noteId);
try {
$this->_getData()->move(
$uid,
$GLOBALS['mnemo_shares']->getShare($newNotepad)->get('folder')
);
$this->_getDataForNotepad($newNotepad)->synchronize();
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
return $uid;
}
/**
* Deletes a note permanently.
*
* @param array $note The note to delete.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
protected function _delete($noteId)
{
$uid = Horde_Url::uriB64Decode($noteId);
try {
$this->_getData()->delete($uid);
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
return $uid;
}
/**
* Deletes all notes from the current notepad.
*
* @return array An array of uids that have been removed.
* @throws Mnemo_Exception
*/
protected function _deleteAll()
{
try {
$uids = $this->_getData()->getObjectIds();
$this->_getData()->deleteAll();
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception($e);
}
return $uids;
}
/**
* Return the Kolab data handler for the current notepad.
*
* @return Horde_Kolab_Storage_Data The data handler.
*/
protected function _getData()
{
if (empty($this->_notepad)) {
throw new Mnemo_Exception(
'The notepad has been left undefined but is required!'
);
}
if ($this->_data === null) {
$this->_data = $this->_getDataForNotepad($this->_notepad);
}
return $this->_data;
}
/**
* Return the Kolab data handler for the specified notepad.
*
* @param string $notepad The notepad name.
*
* @return Horde_Kolab_Storage_Data The data handler.
*/
protected function _getDataForNotepad($notepad)
{
try {
return $this->_kolab->getData(
$GLOBALS['mnemo_shares']->getShare($notepad)->get('folder'),
'note'
);
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Mnemo_Exception(
sprintf(
'Failed retrieving Kolab data for notepad %s: %s',
$notepad,
$e->getMessage()
)
);
}
}
/**
* 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);
}
}
$result = array(
'memolist_id' => $this->_notepad,
'memo_id' => $id,
'uid' => $note['uid'],
'category' => empty($note['categories']) ? '' : $note['categories'][0],
'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;
}
/**
* Generates a local note ID.
*
* @return string A new note ID.
*/
protected function _generateId()
{
return Horde_Url::uriB64Encode($this->_getData()->generateUid());
}
}
mnemo-4.1.2/lib/Driver/Sql.php 0000664 0001750 0001750 00000030602 12233763566 014224 0 ustar jan jan
* @author Michael J. Rubinsky
* @package Mnemo
*/
class Mnemo_Driver_Sql extends Mnemo_Driver
{
/**
* The database connection object.
*
* @var Horde_Db_Adapter
*/
protected $_db;
/**
* Share table name
*
* @var string
*/
protected $_table;
/**
* Charset
*
* @var string
*/
protected $_charset;
/**
* Construct a new SQL storage object.
*
* @param string $notepad The name of the notepad to load/save notes from.
* @param array $params The connection parameters
*
* @throws InvalidArguementException
*/
public function __construct($notepad, $params = array())
{
if (empty($params['db']) || empty($params['table'])) {
throw new InvalidArgumentException('Missing required connection parameter(s).');
}
$this->_notepad = $notepad;
$this->_db = $params['db'];
$this->_table = $params['table'];
$this->_charset = $params['charset'];
}
/**
* Retrieves all of the notes of the current notepad from the backend.
*
* @throws Mnemo_Exception
*/
public function retrieve()
{
$query = sprintf('SELECT * FROM %s WHERE memo_owner = ?', $this->_table);
$values = array($this->_notepad);
try {
$rows = $this->_db->selectAll($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
// Store the retrieved values in a fresh list.
$this->_memos = array();
foreach ($rows as $row) {
$this->_memos[$row['memo_id']] = $this->_buildNote($row);
}
}
/**
* Retrieves one note from the backend.
*
* @param string $noteId The ID of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The array of note attributes.
* @throws Mnemo_Exception
* @throws Horde_Exception_NotFound
*/
public function get($noteId, $passphrase = null)
{
$query = 'SELECT * FROM ' . $this->_table .
' WHERE memo_owner = ? AND memo_id = ?';
$values = array($this->_notepad, $noteId);
try {
$row = $this->_db->selectOne($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
if (!count($row)) {
throw new Horde_Exception_NotFound(_("Not Found"));
}
return $this->_buildNote($row, $passphrase);
}
/**
* Retrieves one note from the backend by UID.
*
* @param string $uid The UID of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The array of note attributes.
* @throws Mnemo_Exception
* @throws Horde_Exception_NotFound
*/
public function getByUID($uid, $passphrase = null)
{
$query = 'SELECT * FROM ' . $this->_table . ' WHERE memo_uid = ?';
$values = array($uid);
try {
$row = $this->_db->selectOne($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
if (!count($row)) {
throw new Horde_Exception_NotFound('Not found');
}
$this->_notepad = $row['memo_owner'];
return $this->_buildNote($row, $passphrase);
}
/**
* Adds a note to the backend storage.
*
* @param string $noteId The ID of the new note.
* @param string $desc The first line of the note.
* @param string $body The whole note body.
* @param string $category The category of the note.
*
* @return string The unique ID of the new note.
* @throws Mnemo_Exception
*/
protected function _add($noteId, $desc, $body, $category)
{
$uid = strval(new Horde_Support_Uuid());
$query = 'INSERT INTO ' . $this->_table
. ' (memo_owner, memo_id, memo_desc, memo_body, memo_category, memo_uid)'
. ' VALUES (?, ?, ?, ?, ?, ?)';
$values = array(
$this->_notepad,
$noteId,
Horde_String::convertCharset($desc, 'UTF-8', $this->_charset),
Horde_String::convertCharset($body, 'UTF-8', $this->_charset),
Horde_String::convertCharset($category, 'UTF-8', $this->_charset),
Horde_String::convertCharset($uid, 'UTF-8', $this->_charset)
);
try {
$this->_db->insert($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e);
}
return $uid;
}
/**
* 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 $category The category of the note.
*
* @throws Mnemo_Exception
*/
protected function _modify($noteId, $desc, $body, $category)
{
$query = 'UPDATE ' . $this->_table
. ' SET memo_desc = ?, memo_body = ?';
$values = array(
Horde_String::convertCharset($desc, 'UTF-8', $this->_charset),
Horde_String::convertCharset($body, 'UTF-8', $this->_charset));
// Don't change the category if it isn't provided.
// @TODO: Category -> Tags
if (!is_null($category)) {
$query .= ', memo_category = ?';
$values[] = Horde_String::convertCharset($category, 'UTF-8', $this->_charset);
}
$query .= ' WHERE memo_owner = ? AND memo_id = ?';
array_push($values, $this->_notepad, $noteId);
try {
$this->_db->update($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e);
}
$note = $this->get($noteId);
return $note['uid'];
}
/**
* Moves a note to a new notepad.
*
* @param string $noteId The note to move.
* @param string $newNotepad The new notepad.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
protected function _move($noteId, $newNotepad)
{
// Get the note's details for use later.
$note = $this->get($noteId);
$query = 'UPDATE ' . $this->_table .
' SET memo_owner = ?' .
' WHERE memo_owner = ? AND memo_id = ?';
$values = array($newNotepad, $this->_notepad, $noteId);
try {
$result = $this->_db->update($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
return $note['uid'];
}
/**
* Deletes a note permanently.
*
* @param array $note The note to delete.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
protected function _delete($noteId)
{
// Get the note's details for use later.
$note = $this->get($noteId);
$query = 'DELETE FROM ' . $this->_table .
' WHERE memo_owner = ? AND memo_id = ?';
$values = array($this->_notepad, $noteId);
try {
$this->_db->delete($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
return $note['uid'];
}
/**
* Deletes all notes from the current notepad.
*
* @return array An array of uids that have been removed.
* @throws Mnemo_Exception
*/
protected function _deleteAll()
{
// Get list of notes we are removing so we can tell history about it.
$query = sprintf('SELECT memo_uid FROM %s WHERE memo_owner = ?',
$this->_table);
$values = array($this->_notepad);
try {
$ids = $this->_db->selectValues($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
$query = sprintf('DELETE FROM %s WHERE memo_owner = ?', $this->_table);
try {
$this->_db->delete($query, $values);
} catch (Horde_Db_Exception $e) {
throw new Mnemo_Exception($e->getMessage());
}
return $ids;
}
/**
*
* @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 = Horde_String::convertCharset($row['memo_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 task based on $row's values.
$memo = array(
'memolist_id' => $row['memo_owner'],
'memo_id' => $row['memo_id'],
'uid' => Horde_String::convertCharset(
$row['memo_uid'], $this->_charset, 'UTF-8'),
'desc' => Horde_String::convertCharset(
$row['memo_desc'], $this->_charset, 'UTF-8'),
'body' => $body,
'category' => Horde_String::convertCharset(
$row['memo_category'], $this->_charset, 'UTF-8'),
'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;
}
/**
* Generates a local note ID.
*
* @return string A new note ID.
*/
protected function _generateId()
{
return strval(new Horde_Support_Randomid());
}
}
mnemo-4.1.2/lib/Factory/Driver.php 0000664 0001750 0001750 00000004036 12233763566 015076 0 ustar jan jan
* @package Mnemo
*/
class Mnemo_Factory_Driver
{
/**
* Instances.
*
* @var array
*/
private $_instances = array();
/**
* The injector.
*
* @var Horde_Injector
*/
private $_injector;
/**
* Constructor.
*
* @param Horde_Injector $injector The injector to use.
*/
public function __construct(Horde_Injector $injector)
{
$this->_injector = $injector;
}
/**
* Return the Mnemo_Driver:: instance.
*
* @param mixed $name The notepad to open
*
* @return Mnemo_Driver
* @throws Mnemo_Exception
*/
public function create($name = '')
{
if (!isset($this->_instances[$name])) {
$driver = $GLOBALS['conf']['storage']['driver'];
$params = Horde::getDriverConfig('storage', $driver);
$class = 'Mnemo_Driver_' . ucfirst(basename($driver));
if (!class_exists($class)) {
throw new Mnemo_Exception(sprintf('Unable to load the definition of %s.', $class));
}
switch ($class) {
case 'Mnemo_Driver_Sql':
$params = array(
'db' => $this->_injector->getInstance('Horde_Db_Adapter'),
'table' => 'mnemo_memos',
'charset' => $params['charset'],
);
break;
case 'Mnemo_Driver_Kolab':
$params = array(
'storage' => $this->_injector->getInstance('Horde_Kolab_Storage')
);
}
$driver = new $class($name, $params);
$this->_instances[$name] = $driver;
}
return $this->_instances[$name];
}
}
mnemo-4.1.2/lib/Factory/Notepads.php 0000664 0001750 0001750 00000004574 12233763566 015427 0 ustar jan jan
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
/**
* The factory for the notepads handler.
*
* Copyright 2011-2013 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (ASL). If you
* did not receive this file, see http://www.horde.org/licenses/apache.
*
* @category Horde
* @package Mnemo
* @author Gunnar Wrobel
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
class Mnemo_Factory_Notepads
{
/**
* Notepads drivers already created.
*
* @var array
*/
private $_instances = array();
/**
* The injector.
*
* @var Horde_Injector
*/
private $_injector;
/**
* Constructor.
*
* @param Horde_Injector $injector The injector to use.
*/
public function __construct(Horde_Injector $injector)
{
$this->_injector = $injector;
}
/**
* Return a Mnemo_Notepads instance.
*
* @return Mnemo_Notepads
*/
public function create()
{
if (!isset($GLOBALS['conf']['notepads']['driver'])) {
$driver = 'Default';
} else {
$driver = Horde_String::ucfirst($GLOBALS['conf']['notepads']['driver']);
}
if (empty($this->_instances[$driver])) {
$class = 'Mnemo_Notepads_' . $driver;
if (class_exists($class)) {
$params = array();
if (!empty($GLOBALS['conf']['share']['auto_create'])) {
$params['auto_create'] = true;
}
switch ($driver) {
case 'Default':
$params['identity'] = $this->_injector->getInstance('Horde_Core_Factory_Identity')->create();
break;
}
$this->_instances[$driver] = new $class(
$GLOBALS['mnemo_shares'],
$GLOBALS['registry']->getAuth(),
$params
);
} else {
throw new Mnemo_Exception(sprintf('Unable to load the definition of %s.', $class));
}
}
return $this->_instances[$driver];
}
} mnemo-4.1.2/lib/Form/CreateNotepad.php 0000664 0001750 0001750 00000002673 12233763566 015662 0 ustar jan jan
* @package Mnemo
*/
class Mnemo_Form_CreateNotepad extends Horde_Form
{
public function __construct(&$vars)
{
parent::__construct($vars, _("Create Notepad"));
$this->addVariable(_("Name"), 'name', 'text', true);
$this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60));
$this->setButtons(array(_("Create")));
}
public function execute()
{
// Create new share.
try {
$notepad = $GLOBALS['mnemo_shares']->newShare($GLOBALS['registry']->getAuth(), strval(new Horde_Support_Uuid()), $this->_vars->get('name'));
$notepad->set('desc', $this->_vars->get('description'));
$GLOBALS['mnemo_shares']->addShare($notepad);
$GLOBALS['display_notepads'][] = $notepad->getName();
$GLOBALS['prefs']->setValue('display_notepads', serialize($GLOBALS['display_notepads']));
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e->getMessage(), 'ERR');
throw new Mnemo_Exception($e);
}
return $notepad;
}
}
mnemo-4.1.2/lib/Form/DeleteNotepad.php 0000664 0001750 0001750 00000004066 12233763566 015657 0 ustar jan jan
* @package Mnemo
*/
class Mnemo_Form_DeleteNotepad extends Horde_Form
{
/**
* Notepad being deleted
*/
protected $_notepad;
/**
* Const'r
*/
public function __construct(&$vars, $notepad)
{
$this->_notepad = $notepad;
parent::__construct($vars, sprintf(_("Delete %s"), $notepad->get('name')));
$this->addHidden('', 'n', 'text', true);
$this->addVariable(sprintf(_("Really delete the notepad \"%s\"? This cannot be undone and all data on this notepad will be permanently removed."), htmlspecialchars($this->_notepad->get('name'))), 'desc', 'description', false);
$this->setButtons(array(
array('class' => 'horde-delete', 'value' => _("Delete")),
array('class' => 'horde-cancel', 'value' => _("Cancel")),
));
}
public function execute()
{
// If cancel was clicked, return false.
if ($this->_vars->get('submitbutton') == _("Cancel")) {
Horde::url('', true)->redirect();
}
if (!$GLOBALS['registry']->getAuth() ||
$this->_notepad->get('owner') != $GLOBALS['registry']->getAuth()) {
throw new Horde_Exception_PermissionDenied(_("Permission denied"));
}
// Delete the notepad.
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create($this->_notepad->getName());
$result = $storage->deleteAll();
// Remove share and all groups/permissions.
try {
$GLOBALS['mnemo_shares']->removeShare($this->_notepad);
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e->getMessage(), 'ERR');
throw new Mnemo_Exception($e->getMessage());
}
}
}
mnemo-4.1.2/lib/Form/EditNotepad.php 0000664 0001750 0001750 00000006343 12233763566 015342 0 ustar jan jan
* @package Mnemo
*/
class Mnemo_Form_EditNotepad extends Horde_Form
{
/**
* Notepad being edited
*/
protected $_notepad;
public function __construct($vars, $notepad)
{
$this->_notepad = $notepad;
$owner = $notepad->get('owner') == $GLOBALS['registry']->getAuth() ||
(is_null($notepad->get('owner')) &&
$GLOBALS['registry']->isAdmin());
parent::__construct(
$vars,
$owner
? sprintf(_("Edit %s"), $notepad->get('name'))
: $notepad->get('name')
);
$this->addHidden('', 'n', 'text', true);
$this->addVariable(_("Name"), 'name', 'text', true);
if (!$owner) {
$v = $this->addVariable(_("Owner"), 'owner', 'text', false);
$owner_name = $GLOBALS['injector']
->getInstance('Horde_Core_Factory_Identity')
->create($notepad->get('owner'))
->getValue('fullname');
if (trim($owner_name) == '') {
$owner_name = $notepad->get('owner');
}
$v->setDefault($owner_name ? $owner_name : _("System"));
}
$this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60));
/* Permissions link. */
if (empty($GLOBALS['conf']['share']['no_sharing']) && $owner) {
$url = Horde::url($GLOBALS['registry']->get('webroot', 'horde')
. '/services/shares/edit.php')
->add(array('app' => 'mnemo', 'share' => $notepad->getName()));
$this->addVariable(
'', '', 'link', false, false, null,
array(array(
'url' => $url,
'text' => _("Change Permissions"),
'onclick' => Horde::popupJs(
$url,
array('params' => array('urlencode' => true)))
. 'return false;',
'class' => 'horde-button',
'target' => '_blank')
)
);
}
$this->setButtons(array(
_("Save"),
array('class' => 'horde-delete', 'value' => _("Delete")),
array('class' => 'horde-cancel', 'value' => _("Cancel"))
));
}
public function execute()
{
switch ($this->_vars->submitbutton) {
case _("Save"):
$this->_notepad->set('name', $this->_vars->get('name'));
$this->_notepad->set('desc', $this->_vars->get('description'));
$this->_notepad->save();
break;
case _("Delete"):
Horde::url('notepads/delete.php')
->add('n', $this->_vars->n)
->redirect();
break;
case _("Cancel"):
Horde::url('', true)->redirect();
break;
}
}
}
mnemo-4.1.2/lib/Notepads/Base.php 0000664 0001750 0001750 00000006600 12233763566 014662 0 ustar jan jan
* @author Gunnar Wrobel
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
/**
* The base functionality of the notepads handler.
*
* Copyright 2001-2013 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (ASL). If you
* did not receive this file, see http://www.horde.org/licenses/apache.
*
* @category Horde
* @package Mnemo
* @author Jon Parise
* @author Gunnar Wrobel
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
abstract class Mnemo_Notepads_Base
{
/**
* The share backend.
*
* @var Horde_Share_Base
*/
protected $_shares;
/**
* The current user.
*
* @var string
*/
protected $_user;
/**
* Additional parameters for the notepad handling.
*
* @var array
*/
protected $_params;
/**
* Constructor.
*
* @param Horde_Share_Base $shares The share backend.
* @param string $user The current user.
* @param array $params Additional parameters.
*/
public function __construct($shares, $user, $params)
{
$this->_shares = $shares;
$this->_user = $user;
$this->_params = $params;
}
/**
* 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();
}
}
/**
* Returns the default share's ID, if it can be determined from the share
* backend.
*
* @return string The default share ID.
*/
public function getDefaultShare()
{
$shares = $this->_shares->listShares(
$this->_user,
array('attributes' => $this->_user)
);
foreach ($shares as $id => $share) {
if ($share->get('default')) {
return $id;
}
}
}
/**
* Runs any actions after setting a new default tasklist.
*
* @param string $share The default share ID.
*/
public function setDefaultShare($share)
{
}
/**
* Return the name of the default share.
*
* @return string The name of a default share.
*/
abstract protected function _getDefaultShareName();
/**
* Add any modifiers required to the share in order to mark it as default.
*
* @param Horde_Share_Object $share The new default share.
*/
protected function _prepareDefaultShare($share)
{
}
} mnemo-4.1.2/lib/Notepads/Default.php 0000664 0001750 0001750 00000003363 12233763566 015377 0 ustar jan jan
* @author Gunnar Wrobel
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
/**
* The default notepads handler.
*
* Copyright 2001-2013 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (ASL). If you
* did not receive this file, see http://www.horde.org/licenses/apache.
*
* @category Horde
* @package Mnemo
* @author Jon Parise
* @author Gunnar Wrobel
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
class Mnemo_Notepads_Default extends Mnemo_Notepads_Base
{
/**
* The current identity.
*
* @var Horde_Prefs_Identity
*/
private $_identity;
/**
* Constructor.
*
* @param Horde_Share_Base $shares The share backend.
* @param string $user The current user.
* @param array $params Additional parameters.
*/
public function __construct($shares, $user, $params)
{
if (!isset($params['identity'])) {
throw new Mnemo_Exception('This notepad handler needs an "identity" parameter!');
} else {
$this->_identity = $params['identity'];
unset($params['identity']);
}
parent::__construct($shares, $user, $params);
}
/**
* Return the name of the default share.
*
* @return string The name of a default share.
*/
protected function _getDefaultShareName()
{
return sprintf(_("Notepad of %s"), $this->_identity->getName());
}
} mnemo-4.1.2/lib/Notepads/Kolab.php 0000664 0001750 0001750 00000003502 12233763566 015036 0 ustar jan jan
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
/**
* The Kolab specific notepads handler.
*
* Copyright 2011-2013 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (ASL). If you
* did not receive this file, see http://www.horde.org/licenses/apache.
*
* @category Horde
* @package Mnemo
* @author Gunnar Wrobel
* @license http://www.horde.org/licenses/apache
* @link http://www.horde.org/apps/mnemo
*/
class Mnemo_Notepads_Kolab extends Mnemo_Notepads_Base
{
/**
* Runs any actions after setting a new default notepad.
*
* @param string $share The default share ID.
*/
public function setDefaultShare($share)
{
$notepads = $this->_shares
->listShares(
$this->_user,
array('perm' => Horde_Perms::SHOW,
'attributes' => $this->_user));
foreach ($notepads as $id => $notepad) {
if ($id == $share) {
$notepad->set('default', true);
$notepad->save();
break;
}
}
}
/**
* Return the name of the default share.
*
* @return string The name of a default share.
*/
protected function _getDefaultShareName()
{
return _("Notes");
}
/**
* Add any modifiers required to the share in order to mark it as default.
*
* @param Horde_Share_Object $share The new default share.
*/
protected function _prepareDefaultShare($share)
{
$share->set('default', true);
}
} mnemo-4.1.2/lib/Api.php 0000664 0001750 0001750 00000040320 12233763566 012741 0 ustar jan jan removeUserData($user, 'mnemo');
} catch (Horde_Exception $e) {
throw new Mnemo_Exception($e);
}
}
/**
* @param boolean $owneronly Only return notepads that this user owns?
* Defaults to false.
* @param integer $permission The permission to filter notepads by.
*
* @return array The notepads.
*/
public function listNotepads($owneronly, $permission)
{
return Mnemo::listNotepads($owneronly, $permission);
}
/**
* Returns an array of UIDs for all notes that the current user is authorized
* to see.
*
* @param string $notepad The notepad to list notes from.
*
* @return array An array of UIDs for all notes the user can access.
* @throws Mnemo_Exception
* @throws Horde_Exception_PermissionDenied
*/
public function listUids($notepad = null)
{
global $conf;
if (!isset($conf['storage']['driver'])) {
throw new Mnemo_Exception('Not configured');
}
// Make sure we have a valid notepad.
if (empty($notepad)) {
$notepad = Mnemo::getDefaultNotepad();
}
if (!array_key_exists($notepad, Mnemo::listNotepads(false, Horde_Perms::READ))) {
throw new Horde_Exception_PermissionDenied();
}
// Set notepad for listMemos.
$GLOBALS['display_notepads'] = array($notepad);
$memos = Mnemo::listMemos();
$uids = array();
foreach ($memos as $memo) {
$uids[] = $memo['uid'];
}
return $uids;
}
/**
* Method for obtaining all server changes between two timestamps. Basically
* a wrapper around listBy(), but returns an array containing all adds,
* edits and deletions.
*
* @param integer $start The starting timestamp
* @param integer $end The ending timestamp.
* @param boolean $isModSeq If true, $timestamp and $end are
* modification sequences and not
* timestamps. @since 4.1.1
*
* @return array An hash with 'add', 'modify' and 'delete' arrays.
* @since 3.0.5
*/
public function getChanges($start, $end, $isModSeq = false)
{
return array('add' => $this->listBy('add', $start, null, $end, $isModSeq),
'modify' => $this->listBy('modify', $start, null, $end, $isModSeq),
'delete' => $this->listBy('delete', $start, null, $end, $isModSeq));
}
/**
* Return all changes occuring between the specified modification
* sequences.
*
* @param integer $start The starting modseq.
* @param integer $end The ending modseq.
*
* @return array The changes @see getChanges()
* @since 4.1.1
*/
public function getChangesByModSeq($start, $end)
{
return $this->getChanges($start, $end, true);
}
/**
* Returns an array of UIDs for notes that have had $action happen since
* $timestamp.
*
* @param string $action The action to check for - add, modify, or delete.
* @param integer $timestamp The time to start the search.
* @param string $notepad The notepad to search in.
* @param integer $end The optional ending timestamp.
* @param boolean $isModSeq If true, $timestamp and $end are modification
* sequences and not timestamps. @since 4.1.1
*
* @return array An array of UIDs matching the action and time criteria.
*/
public function listBy($action, $timestamp, $notepad = null, $end = null, $isModSeq = false)
{
/* Make sure we have a valid notepad. */
if (empty($notepad)) {
$notepad = Mnemo::getDefaultNotepad();
}
if (!array_key_exists($notepad, Mnemo::listNotepads(false, Horde_Perms::READ))) {
throw new Horde_Exception_PermissionDenied();
}
$filter = array(array('op' => '=', 'field' => 'action', 'value' => $action));
if (!empty($end) && !$isModSeq) {
$filter[] = array('op' => '<', 'field' => 'ts', 'value' => $end);
}
$history = $GLOBALS['injector']->getInstance('Horde_History');
if (!$isModSeq) {
$histories = $history->getByTimestamp('>', $timestamp, $filter, 'mnemo:' . $notepad);
} else {
$histories = $history->getByModSeq($timestamp, $end, $filter, 'mnemo:' . $notepad);
}
// Strip leading mnemo:username:.
return preg_replace('/^([^:]*:){2}/', '', array_keys($histories));
}
/**
* Returns the timestamp of an operation for a given uid an action.
*
* @param string $uid The uid to look for.
* @param string $action The action to check for - add, modify, or delete.
* @param string $notepad The notepad to search in.
* @param boolean $modSeq Request a modification sequence instead of a
* timestamp. @since 4.1.1
*
* @return integer The timestamp or modseq for this action.
* @throws Horde_Exception_PermissionDenied
*/
public function getActionTimestamp($uid, $action, $notepad = null, $modSeq = false)
{
/* Make sure we have a valid notepad. */
if (empty($notepad)) {
$notepad = Mnemo::getDefaultNotepad();
}
if (!array_key_exists($notepad, Mnemo::listNotepads(false, Horde_Perms::READ))) {
throw new Horde_Exception_PermissionDenied();
}
$history = $GLOBALS['injector']->getInstance('Horde_History');
if (!$modSeq) {
return $history->getActionTimestamp('mnemo:' . $notepad . ':' . $uid, $action);
} else {
return $history->getActionModSeq('mnemo:' . $notepad . ':' . $uid, $action);
}
}
/**
* Return the largest modification sequence from the history backend.
*
* @return integer The modseq.
* @since 4.1.1
*/
public function getHighestModSeq()
{
return $GLOBALS['injector']->getInstance('Horde_History')->getHighestModSeq('mnemo');
}
/**
* Import a memo represented in the specified contentType.
*
* @param string $content The content of the memo.
* @param string $contentType What format is the data in? Currently supports:
* text/plain
* text/x-vnote
* activesync
* @param string $notepad (optional) The notepad to save the memo on.
*
* @return string The new UID, or false on failure.
* @throws Mnemo_Exception
* @throws Horde_Exception_PermissionDenied
*/
public function import($content, $contentType, $notepad = null)
{
global $prefs;
/* Make sure we have a valid notepad and permissions to edit
* it. */
if (empty($notepad)) {
$notepad = Mnemo::getDefaultNotepad(Horde_Perms::EDIT);
}
if (!array_key_exists($notepad, Mnemo::listNotepads(false, Horde_Perms::EDIT))) {
throw new Horde_Exception_PermissionDenied();
}
/* Create a Mnemo_Driver instance. */
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create($notepad);
switch ($contentType) {
case 'text/plain':
$noteId = $storage->add($storage->getMemoDescription($content), $content);
break;
case 'text/x-vnote':
if (!($content instanceof Horde_Icalendar_Vnote)) {
$iCal = new Horde_Icalendar();
if (!$iCal->parsevCalendar($content)) {
throw new Mnemo_Exception(_("There was an error importing the iCalendar data."));
}
$components = $iCal->getComponents();
switch (count($components)) {
case 0:
throw new Mnemo_Exception(_("No iCalendar data was found."));
case 1:
$content = $components[0];
break;
default:
$ids = array();
foreach ($components as $content) {
if ($content instanceof Horde_Icalendar_Vnote) {
$note = $storage->fromiCalendar($content);
$noteId = $storage->add(
$note['desc'], $note['body'],
!empty($note['category']) ? $note['category'] : '');
$ids[] = $noteId;
}
}
return $ids;
}
}
$note = $storage->fromiCalendar($content);
$noteId = $storage->add(
$note['desc'], $note['body'],
!empty($note['category']) ? $note['category'] : '');
break;
case 'activesync':
$category = is_array($content->categories) ? current($content->categories) : '';
// We only support plaintext
if ($content->body->type == Horde_ActiveSync::BODYPREF_TYPE_HTML) {
$body = Horde_Text_Filter::filter($content->body->data, 'Html2text');
} else {
$body = $content->body->data;
}
$noteId = $storage->add($content->subject, $body, $category);
break;
default:
throw new Mnemo_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType));
}
$note = $storage->get($noteId);
return $note['uid'];
}
/**
* Export a memo, identified by UID, in the requested contentType.
*
* @param string $uid Identify the memo to export.
* @param string $contentType What format should the data be in?
* A string with one of:
*
* 'text/plain'
* 'text/x-vnote'
* 'activesync'
*
* @param array $options Any additional options to be passed to the
* exporter.
*
* @return string The requested data
* @throws Mnemo_Exception
* @throws Horde_Exception_PermissionDenied
*/
public function export($uid, $contentType, array $options = array())
{
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create();
try {
$memo = $storage->getByUID($uid);
} catch (Mnemo_Exception $e) {
if ($e->getCode() == Mnemo::ERR_NO_PASSPHRASE ||
$e->getCode() == Mnemo::ERR_DECRYPT) {
$memo['body'] = _("This note has been encrypted.");
} else {
throw $e;
}
}
if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, Horde_Perms::READ))) {
throw new Horde_Exception_PermissionDenied();
}
switch ($contentType) {
case 'text/plain':
return $memo['body'];
case 'text/x-vnote':
// Create the new iCalendar container.
$iCal = new Horde_Icalendar('1.1');
$iCal->setAttribute('VERSION', '1.1');
$iCal->setAttribute('PRODID', '-//The Horde Project//Mnemo ' . $GLOBALS['registry']->getVersion() . '//EN');
$iCal->setAttribute('METHOD', 'PUBLISH');
// Create a new vNote.
$vNote = $storage->toiCalendar($memo, $iCal);
return $vNote->exportvCalendar();
case 'activesync':
return $storage->toASNote($memo, $options);
}
throw new Mnemo_Exception(sprintf(_("Unsupported Content-Type: %s"),$contentType));
}
/**
* Delete a memo identified by UID.
*
* @param string | array $uid Identify the note to delete, either a
* single UID or an array.
* @throws Horde_Exception_PermissionDenied
*/
public function delete($uid)
{
// Handle an arrray of UIDs for convenience of deleting multiple
// notes at once.
if (is_array($uid)) {
foreach ($uid as $u) {
$result = $this->delete($u);
}
return;
}
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create();
$memo = $storage->getByUID($uid);
if (!$GLOBALS['registry']->isAdmin() &&
!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, Horde_Perms::DELETE))) {
throw new Horde_Exception_PermissionDenied();
}
$storage->delete($memo['memo_id']);
}
/**
* Replace the memo identified by UID with the content represented in
* the specified contentType.
*
* @param string $uid Idenfity the memo to replace.
* @param string $content The content of the memo.
* @param string $contentType What format is the data in? Currently supports:
* text/plain
* text/x-vnote
* activesync
* @throws Mnemo_Exception
* @throws Horde_Exception_PermissionDenied
*/
public function replace($uid, $content, $contentType)
{
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create();
$memo = $storage->getByUID($uid);
if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, Horde_Perms::EDIT))) {
throw new Horde_Exception_PermissionDenied();
}
switch ($contentType) {
case 'text/plain':
$storage->modify($memo['memo_id'], $storage->getMemoDescription($content), $content, null);
break;
case 'text/x-vnote':
if (!($content instanceof Horde_Icalendar_Vnote)) {
$iCal = new Horde_Icalendar();
if (!$iCal->parsevCalendar($content)) {
throw new Mnemo_Exception(_("There was an error importing the iCalendar data."));
}
$components = $iCal->getComponents();
switch (count($components)) {
case 0:
throw new Mnemo_Exception(_("No iCalendar data was found."));
case 1:
$content = $components[0];
break;
default:
throw new Mnemo_Exception(_("Multiple iCalendar components found; only one vNote is supported."));
}
}
$note = $storage->fromiCalendar($content);
$storage->modify($memo['memo_id'],
$note['desc'],
$note['body'],
!empty($note['category']) ? $note['category'] : '');
break;
case 'activesync':
$category = is_array($content->categories) ? current($content->categories) : '';
// We only support plaintext
if ($content->body->type == Horde_ActiveSync::BODYPREF_TYPE_HTML) {
$body = Horde_Text_Filter::filter($content->body->data, 'Html2text');
} else {
$body = $content->body->data;
}
$storage->modify($memo['memo_id'], $content->subject, $body, $category);
break;
default:
throw new Mnemo_Exception(sprintf(_("Unsupported Content-Type: %s"),$contentType));
}
}
}
mnemo-4.1.2/lib/Application.php 0000664 0001750 0001750 00000021032 12233763566 014472 0 ustar jan jan true,
'modseq' => true,
);
/**
*/
public $version = 'H5 (4.1.2)';
/**
* Global variables defined:
* $mnemo_shares - TODO
*/
protected function _init()
{
Mnemo::initialize();
}
/**
*/
public function perms()
{
return array(
'max_notes' => array(
'title' => _("Maximum Number of Notes"),
'type' => 'int'
)
);
}
/**
*/
public function menu($menu)
{
global $conf, $injector;
$menu->add(Horde::url('list.php'), _("_List Notes"), 'mnemo-list', null, null, null, basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null);
/* Search. */
$menu->add(Horde::url('search.php'), _("_Search"), 'mnemo-search');
/* Import/Export */
if ($conf['menu']['import_export']) {
$menu->add(Horde::url('data.php'), _("_Import/Export"), 'horde-data');
}
}
/**
* Add additional items to the sidebar.
*
* @param Horde_View_Sidebar $sidebar The sidebar object.
*/
public function sidebar($sidebar)
{
$perms = $GLOBALS['injector']->getInstance('Horde_Core_Perms');
if (Mnemo::getDefaultNotepad(Horde_Perms::EDIT) &&
($perms->hasAppPermission('max_notes') === true ||
$perms->hasAppPermission('max_notes') > Mnemo::countMemos())) {
$sidebar->addNewButton(
_("_New Note"),
Horde::url('memo.php')->add('actionID', 'add_memo'));
}
$url = Horde::url('');
$edit = Horde::url('notepads/edit.php');
$user = $GLOBALS['registry']->getAuth();
$sidebar->containers['my'] = array(
'header' => array(
'id' => 'mnemo-toggle-my',
'label' => _("My Notepads"),
'collapsed' => false,
),
);
if (!$GLOBALS['prefs']->isLocked('default_notepad')) {
$sidebar->containers['my']['header']['add'] = array(
'url' => Horde::url('notepads/create.php'),
'label' => _("Create a new Notepad"),
);
}
$sidebar->containers['shared'] = array(
'header' => array(
'id' => 'mnemo-toggle-shared',
'label' => _("Shared Notepads"),
'collapsed' => true,
),
);
foreach (Mnemo::listNotepads() as $name => $notepad) {
$row = array(
'selected' => in_array($name, $GLOBALS['display_notepads']),
'url' => $url->add('display_notepad', $name),
'label' => Mnemo::getLabel($notepad),
'color' => $notepad->get('color') ?: '#dddddd',
'edit' => $edit->add('n', $notepad->getName()),
'type' => 'checkbox',
);
if ($notepad->get('owner') == $user) {
$sidebar->addRow($row, 'my');
} else {
$sidebar->addRow($row, 'shared');
}
}
}
/**
*/
public function hasPermission($permission, $allowed, $opts = array())
{
if (is_array($allowed)) {
switch ($permission) {
case 'max_notes':
$allowed = max($allowed);
break;
}
}
return $allowed;
}
/* Topbar method. */
/**
*/
public function topbarCreate(Horde_Tree_Renderer_Base $tree, $parent = null,
array $params = array())
{
$add = Horde::url('memo.php')->add('actionID', 'add_memo');
$tree->addNode(array(
'id' => $parent . '__new',
'parent' => $parent,
'label' => _("New Note"),
'expanded' => false,
'params' => array(
'icon' => Horde_Themes::img('add.png'),
'url' => $add
)
));
foreach (Mnemo::listNotepads(false, Horde_Perms::EDIT) as $name => $notepad) {
$tree->addNode(array(
'id' => $parent . $name . '__new',
'parent' => $parent . '__new',
'label' => sprintf(_("in %s"), Mnemo::getLabel($notepad)),
'expanded' => false,
'params' => array(
'icon' => Horde_Themes::img('add.png'),
'url' => $add->copy()->add('memolist', $name)
)
));
}
$tree->addNode(array(
'id' => $parent . '__search',
'parent' => $parent,
'label' => _("Search"),
'expanded' => false,
'params' => array(
'icon' => Horde_Themes::img('search.png'),
'url' => Horde::url('search.php')
)
));
}
/**
*/
public function removeUserData($user)
{
$error = false;
$notepads = $GLOBALS['mnemo_shares']->listShares(
$user, array('attributes' => $user));
foreach ($notepads as $notepad => $share) {
$driver = $GLOBALS['injector']
->getInstance('Mnemo_Factory_Driver')
->create($notepad);
try {
$driver->deleteAll();
} catch (Mnemo_Exception $e) {
Horde::logMessage($e, 'NOTICE');
$error = true;
}
try {
$GLOBALS['mnemo_shares']->removeShare($share);
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e, 'NOTICE');
$error = true;
}
}
// Get a list of all shares this user has perms to and remove the perms.
try {
$shares = $GLOBALS['mnemo_shares']->listShares($user);
foreach ($shares as $share) {
$share->removeUser($user);
}
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e, 'NOTICE');
$error = true;
}
if ($error) {
throw new Mnemo_Exception(sprintf(_("There was an error removing notes for %s. Details have been logged."), $user));
}
}
/* Download data. */
/**
* @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']
);
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;
}
}
}
/**
*/
public function cleanupData()
{
$GLOBALS['import_step'] = 1;
return Horde_Data::IMPORT_FILE;
}
}
mnemo-4.1.2/lib/Driver.php 0000664 0001750 0001750 00000037134 12233763566 013474 0 ustar jan jan
* @author Michael J. Rubinsky
* @package Mnemo
*/
abstract class Mnemo_Driver
{
/**
* Array holding the current memo list. Each array entry is a hash
* describing a memo. The array is indexed numerically by memo ID.
*
* @var array
*/
protected $_memos = array();
/**
* String containing the current notepad name.
*
* @var string
*/
protected $_notepad = '';
/**
* Crypting processor.
*
* @var Horde_Crypt_pgp
*/
protected $_pgp;
/**
* Retrieves all of the notes of the current notepad from the backend.
*
* @thows Mnemo_Exception
*/
abstract public function retrieve();
/**
* Lists memos based on the given criteria. All memos will be
* returned by default.
*
* @return array Returns a list of the requested memos.
*/
public function listMemos()
{
return $this->_memos;
}
/**
* Update the description (short summary) of a memo.
*
* @param integer $memo_id The memo to update.
*/
public function getMemoDescription($body)
{
if (!strstr($body, "\n") && Horde_String::length($body) <= 64) {
return trim($body);
}
$lines = explode("\n", $body);
if (!is_array($lines)) {
return trim(Horde_String::substr($body, 0, 64));
}
// Move to a line with more than spaces.
$i = 0;
while (isset($lines[$i]) && !preg_match('|[^\s]|', $lines[$i])) {
$i++;
}
if (Horde_String::length($lines[$i]) <= 64) {
return trim($lines[$i]);
} else {
return trim(Horde_String::substr($lines[$i], 0, 64));
}
}
/**
* Retrieves one note from the backend.
*
* @param string $noteId The ID of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The array of note attributes.
* @throws Mnemo_Exception
* @throws Horde_Exception_NotFound
*/
abstract public function get($noteId, $passphrase = null);
/**
* Retrieves one note from the backend by UID.
*
* @param string $uid The UID of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The array of note attributes.
* @throws Mnemo_Exception
* @throws Horde_Exception_NotFound
*/
abstract public function getByUID($uid, $passphrase = null);
/**
* Adds a note to the backend storage.
*
* @param string $desc The first line of the note.
* @param string $body The whole note body.
* @param string $category The category of the note.
* @param string $passphrase The passphrase to encrypt the note with.
*
* @return string The ID of the new note.
* @throws Mnemo_Exception
*/
public function add($desc, $body, $category = '', $passphrase = null)
{
$noteId = $this->_generateId();
if ($passphrase) {
$body = $this->_encrypt($body, $passphrase);
Mnemo::storePassphrase($noteId, $passphrase);
}
$uid = $this->_add($noteId, $desc, $body, $category);
// Log the creation of this item in the history log.
try {
$GLOBALS['injector']->getInstance('Horde_History')
->log('mnemo:' . $this->_notepad . ':' . $uid,
array('action' => 'add'), true);
} catch (Horde_Exception $e) {
}
return $noteId;
}
/**
* Adds a note to the backend storage.
*
* @param string $noteId The ID of the new note.
* @param string $desc The first line of the note.
* @param string $body The whole note body.
* @param string $category The category of the note.
*
* @return string The unique ID of the new note.
* @throws Mnemo_Exception
*/
abstract protected function _add($noteId, $desc, $body, $category);
/**
* 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 $category The category of the note.
* @param string $passphrase The passphrase to encrypt the note with.
*
* @throws Mnemo_Exception
*/
public function modify($noteId, $desc, $body, $category = null,
$passphrase = null)
{
if ($passphrase) {
$body = $this->_encrypt($body, $passphrase);
Mnemo::storePassphrase($noteId, $passphrase);
}
$uid = $this->_modify($noteId, $desc, $body, $category);
// 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) {
}
}
}
/**
* 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 $category The category of the note.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
abstract protected function _modify($noteId, $desc, $body, $category);
/**
* Moves a note to a new notepad.
*
* @param string $noteId The note to move.
* @param string $newNotepad The new notepad.
*
* @throws Mnemo_Exception
*/
public function move($noteId, $newNotepad)
{
$uid = $this->_move($noteId, $newNotepad);
// Log the moving of this item in the history log.
if ($uid) {
try {
$history = $GLOBALS['injector']->getInstance('Horde_History');
$history->log('mnemo:' . $this->_notepad . ':' . $uid,
array('action' => 'delete'), true);
$history->log('mnemo:' . $newNotepad . ':' . $uid,
array('action' => 'add'), true);
} catch (Horde_Exception $e) {
}
}
}
/**
* Moves a note to a new notepad.
*
* @param string $noteId The note to move.
* @param string $newNotepad The new notepad.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
abstract protected function _move($noteId, $newNotepad);
/**
* Deletes a note permanently.
*
* @param string $noteId The note to delete.
*
* @throws Mnemo_Exception
*/
public function delete($noteId)
{
$uid = $this->_delete($noteId);
// Log the deletion of this item in the history log.
if ($uid) {
try {
$GLOBALS['injector']->getInstance('Horde_History')
->log('mnemo:' . $this->_notepad . ':' . $uid,
array('action' => 'delete'), true);
} catch (Horde_Exception $e) {
}
}
}
/**
* Deletes a note permanently.
*
* @param array $note The note to delete.
*
* @return string The note's UID.
* @throws Mnemo_Exception
*/
abstract protected function _delete($noteId);
/**
* Deletes all notes from the current notepad.
*
* @throws Mnemo_Exception
*/
public function deleteAll()
{
$uids = $this->_deleteAll();
// Update History.
$history = $GLOBALS['injector']->getInstance('Horde_History');
try {
foreach ($uids as $uid) {
$history->log(
'mnemo:' . $this->_notepad . ':' . $uid,
array('action' => 'delete'),
true);
}
} catch (Horde_Exception $e) {
}
}
/**
* Deletes all notes from the current notepad.
*
* @return array An array of uids that have been removed.
* @throws Mnemo_Exception
*/
abstract protected function _deleteAll();
/**
* Loads the PGP encryption driver.
*
* @TODO: Inject *into* driver from the factory binder
*/
protected function _loadPGP()
{
if (empty($GLOBALS['conf']['gnupg']['path'])) {
throw new Mnemo_Exception(_("Encryption support has not been configured, please contact your administrator."));
}
$this->_pgp = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Crypt')->create('pgp', array(
'program' => $GLOBALS['conf']['gnupg']['path']
));
}
/**
* Encrypts a note.
*
* @param string $note The note text.
* @param string $passphrase The passphrase to encrypt the note with.
*
* @return string The encrypted text.
*/
protected function _encrypt($note, $passphrase)
{
$this->_loadPGP();
return $this->_pgp->encrypt($note, array('type' => 'message', 'symmetric' => true, 'passphrase' => $passphrase));
}
/**
* Decrypts a note.
*
* @param string $note The encrypted note text.
* @param string $passphrase The passphrase to decrypt the note with.
*
* @return string The decrypted text.
* @throws Mnemo_Exception
*/
protected function _decrypt($note, $passphrase)
{
$this->_loadPGP();
try {
return $this->_pgp->decrypt($note, array('type' => 'message', 'passphrase' => $passphrase));
} catch (Horde_Crypt_Exception $e) {
throw new Mnemo_Exception($e->getMessage(), Mnemo::ERR_DECRYPT);
}
}
/**
* Returns whether note encryption is supported.
*
* Checks if PGP support could be loaded, if it supports symmetric
* encryption, and if we have a secure connection.
*
* @return boolean Whether encryption is suppoted.
*/
public function encryptionSupported()
{
try {
$this->_loadPGP();
} catch (Mnemo_Exception $e) {
}
return (is_callable(array($this->_pgp, 'encryptedSymmetrically')) &&
Horde::isConnectionSecure());
}
/**
* Create an AS memo from this task
*
* @param array $memo A memo array.
* @param array $options
*
* @return Horde_ActiveSync_Message_Note
*/
public function toASNote($memo, $options = array())
{
$message = new Horde_ActiveSync_Message_Note(array(
'protocolversion' => $options['protocolversion']));
$message->subject = $memo['desc'];
$bp = $options['bodyprefs'];
$body = new Horde_ActiveSync_Message_AirSyncBaseBody();
if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML])) {
$body->type = Horde_ActiveSync::BODYPREF_TYPE_HTML;
$memo['body'] = Horde_Text_Filter::filter($memo['body'], 'Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']) &&
Horde_String::length($memo['body']) > $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']) {
$body->data = Horde_String::substr($memo['body'], $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']);
$body->truncated = 1;
} else {
$body->data = $memo['body'];
}
} else {
$body->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) {
if (Horde_String::length($memo['body']) > $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']) {
$body->data = Horde_String::substr($memo['body'], 0, $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']);
$body->truncated = 1;
} else {
$body->data = $memo['body'];
}
}
}
$body->estimateddatasize = Horde_String::length($memo['body']);
$message->body = $body;
if (!empty($memo['category'])) {
$message->categories = array($memo['category']);
}
$history = $GLOBALS['injector']->getInstance('Horde_History');
$last = $history->getActionTimeStamp('mnemo:' . $memo['memolist_id'] . ':' . $memo['uid'], 'modify');
if (empty($last)) {
$last = $history->getActionTimeStamp('mnemo:' . $memo['memolist_id'] . ':' . $memo['uid'], 'add');
}
$message->lastmodified = new Horde_Date($last);
return $message;
}
/**
* Export this memo in iCalendar format.
*
* @param array memo The memo (hash array) to export
* @param Horde_Icalendar A Horde_Icalendar object that acts as container.
*
* @return Horde_Icalendar_Vnote object for this event.
*/
public function toiCalendar($memo, $calendar)
{
global $prefs;
$vnote = Horde_Icalendar::newComponent('vnote', $calendar);
$vnote->setAttribute('UID', $memo['uid']);
$vnote->setAttribute('BODY', $memo['body']);
$vnote->setAttribute('SUMMARY', $memo['desc']);
if (!empty($memo['category'])) {
$vnote->setAttribute('CATEGORIES', $memo['category']);
}
/* Get the note's history. */
$history = $GLOBALS['injector']->getInstance('Horde_History');
$log = $history->getHistory('mnemo:' . $memo['memolist_id'] . ':' . $memo['uid']);
if ($log) {
foreach ($log as $entry) {
switch ($entry['action']) {
case 'add':
$created = $entry['ts'];
break;
case 'modify':
$modified = $entry['ts'];
break;
}
}
}
if (!empty($created)) {
$vnote->setAttribute('DCREATED', $created);
}
if (!empty($modified)) {
$vnote->setAttribute('LAST-MODIFIED', $modified);
}
return $vnote;
}
/**
* Create a memo (hash array) from a Horde_Icalendar_Vnote object.
*
* @param Horde_Icalendar_Vnote $vnote The iCalendar data to update from.
*
* @return array Memo (hash array) created from the vNote.
*/
public function fromiCalendar(Horde_Icalendar_Vnote $vNote)
{
$memo = array();
try {
$body = $vNote->getAttribute('BODY');
} catch (Horde_Icalendar_Exception $e) {
}
if (!is_array($body)) {
$memo['body'] = $body;
} else {
$memo['body'] = '';
}
$memo['desc'] = $this->getMemoDescription($memo['body']);
try {
$cat = $vNote->getAttribute('CATEGORIES');
} catch (Horde_Icalendar_Exception $e) {
}
if (!is_array($cat)) {
$memo['category'] = $cat;
}
return $memo;
}
/**
* Generates a local note ID.
*
* @return string A new note ID.
*/
abstract protected function _generateId();
}
mnemo-4.1.2/lib/Exception.php 0000664 0001750 0001750 00000000604 12233763566 014167 0 ustar jan jan
* @package Mnemo
*/
class Mnemo_Exception extends Horde_Exception_Wrapped
{
}
mnemo-4.1.2/lib/Mnemo.php 0000664 0001750 0001750 00000043426 12233763566 013315 0 ustar jan jan
* @package Mnemo
*/
class Mnemo
{
/**
* Sort by memo description.
*/
const SORT_DESC = 0;
/**
* Sort by memo category.
*/
const SORT_CATEGORY = 1;
/**
* Sort by notepad.
*/
const SORT_NOTEPAD = 2;
/**
* Sort by moddate
*/
const SORT_MOD_DATE = 3;
/**
* Sort in ascending order.
*/
const SORT_ASCEND = 0;
/**
* Sort in descending order.
*/
const SORT_DESCEND = 1;
/**
* No passphrase provided.
*/
const ERR_NO_PASSPHRASE = 100;
/**
* Decrypting failed
*/
const ERR_DECRYPT = 101;
/**
* Retrieves the current user's note list from storage. This function will
* also sort the resulting list, if requested.
*
* @param constant $sortby The field by which to sort. (self::SORT_DESC,
* self::SORT_CATEGORY, self::SORT_NOTEPAD,
* self::SORT_MOD_DATE)
* @param constant $sortdir The direction by which to sort.
* (self::SORT_ASC, self::SORT_DESC)
*
* @return array A list of the requested notes.
*
* @see Mnemo_Driver::listMemos()
*/
public static function listMemos($sortby = self::SORT_DESC,
$sortdir = self::SORT_ASCEND)
{
global $conf, $display_notepads;
$memos = array();
/* Sort the memo list. */
$sort_functions = array(
self::SORT_DESC => 'ByDesc',
self::SORT_CATEGORY => 'ByCategory',
self::SORT_NOTEPAD => 'ByNotepad',
self::SORT_MOD_DATE => 'ByModDate'
);
foreach ($display_notepads as $notepad) {
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create($notepad);
try {
$storage->retrieve();
} catch (Mnemo_Exception $e) {
$GLOBALS['notification']->push($e, 'horde.error');
}
$newmemos = $storage->listMemos();
$memos = array_merge($memos, $newmemos);
}
// Sort the array if we have a sort function defined
if (isset($sort_functions[$sortby])) {
$prefix = ($sortdir == self::SORT_DESCEND) ? '_rsort' : '_sort';
uasort($memos, array('Mnemo', $prefix . $sort_functions[$sortby]));
}
return $memos;
}
/**
* Returns the number of notes in notepads that the current user owns.
*
* @return integer The number of notes that the user owns.
*/
public static function countMemos()
{
static $count;
if (isset($count)) {
return $count;
}
$notepads = self::listNotepads(true, Horde_Perms::ALL);
$count = 0;
foreach (array_keys($notepads) as $notepad) {
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create($notepad);
$storage->retrieve();
$count += count($storage->listMemos());
}
return $count;
}
/**
* Retrieves a specific note from storage.
*
* @param string $notepad The notepad to retrieve the note from.
* @param string $noteId The Id of the note to retrieve.
* @param string $passphrase A passphrase with which this note was
* supposed to be encrypted.
*
* @return array The note.
*/
public static function getMemo($notepad, $noteId, $passphrase = null)
{
$storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create($notepad);
return $storage->get($noteId, $passphrase);
}
/**
* Get preview text for a note (the first 20 lines or so).
*
* @param array $note The note array
*
* @return string A few lines of the note for previews or tooltips.
*/
public static function getNotePreview($note)
{
$body = $note['body'];
if ($body instanceof Mnemo_Exception) {
$body = $body->getMessage();
}
$lines = explode("\n", wordwrap($body));
return implode("\n", array_splice($lines, 0, 20));
}
/**
* Lists all notepads a user has access to.
*
* This method takes the $conf['share']['hidden'] setting into account. If
* this setting is enabled, even if requesting permissions different than
* SHOW, it will only return calendars that the user owns or has SHOW
* permissions for. For checking individual calendar's permissions, use
* hasPermission() instead.
*
* @param boolean $owneronly Only return memo lists that this user owns?
* Defaults to false.
* @param integer $permission The permission to filter notepads by.
*
* @return array The memo lists.
*/
public static function listNotepads($owneronly = false,
$permission = Horde_Perms::SHOW)
{
if ($owneronly && !$GLOBALS['registry']->getAuth()) {
return array();
}
if ($owneronly || empty($GLOBALS['conf']['share']['hidden'])) {
try {
$notepads = $GLOBALS['mnemo_shares']->listShares(
$GLOBALS['registry']->getAuth(),
array('perm' => $permission,
'attributes' => $owneronly ? $GLOBALS['registry']->getAuth() : null,
'sort_by' => 'name'));
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e->getMessage(), 'ERR');
return array();
}
} else {
try {
$notepads = $GLOBALS['mnemo_shares']->listShares(
$GLOBALS['registry']->getAuth(),
array('perm' => $permission,
'attributes' => $GLOBALS['registry']->getAuth(),
'sort_by' => 'name'));
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e);
return array();
}
$display_notepads = @unserialize($GLOBALS['prefs']->getValue('display_notepads'));
if (is_array($display_notepads)) {
foreach ($display_notepads as $id) {
try {
$notepad = $GLOBALS['mnemo_shares']->getShare($id);
if ($notepad->hasPermission($GLOBALS['registry']->getAuth(), $permission)) {
$notepads[$id] = $notepad;
}
} catch (Horde_Exception_NotFound $e) {
} catch (Horde_Share_Exception $e) {
Horde::logMessage($e);
return array();
}
}
}
}
return $notepads;
}
/**
* Returns the default notepad for the current user at the specified
* permissions level.
*
* @param integer $permission Horde_Perms constant for permission level
* required.
*
* @return string The notepad identifier, or null if none.
*/
public static function getDefaultNotepad($permission = Horde_Perms::SHOW)
{
$notepads = self::listNotepads(false, $permission);
$default_notepad = $GLOBALS['prefs']->getValue('default_notepad');
if (isset($notepads[$default_notepad])) {
return $default_notepad;
}
$default_notepad = $GLOBALS['injector']
->getInstance('Mnemo_Factory_Notepads')
->create()
->getDefaultShare();
if (isset($notepads[$default_notepad])) {
$GLOBALS['prefs']->setValue('default_notepad', $default_notepad);
return $default_notepad;
}
reset($notepads);
return key($notepads);
}
/**
* Returns the label to be used for a notepad.
*
* Attaches the owner name of shared notepads if necessary.
*
* @param Horde_Share_Object A notepad.
*
* @return string The notepad's label.
*/
public static function getLabel($notepad)
{
$label = $notepad->get('name');
if ($notepad->get('owner') &&
$notepad->get('owner') != $GLOBALS['registry']->getAuth()) {
$label .= ' [' . $GLOBALS['registry']->convertUsername($notepad->get('owner'), false) . ']';
}
return $label;
}
/**
* Returns the real name, if available, of a user.
*
* @return string The real name
*/
public static function getUserName($uid)
{
static $names = array();
if (!isset($names[$uid])) {
$ident = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($uid);
$ident->setDefault($ident->getDefault());
$names[$uid] = $ident->getValue('fullname');
if (empty($names[$uid])) {
$names[$uid] = $uid;
}
}
return $names[$uid];
}
/**
* Comparison function for sorting notes by description.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer 1 if memo one is greater, -1 if memo two is greater; 0
* if they are equal.
*/
protected static function _sortByDesc($a, $b)
{
return strcoll($a['desc'], $b['desc']);
}
/**
* Comparison function for reverse sorting notes by description.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer -1 if note one is greater, 1 if note two is greater; 0
* if they are equal.
*/
protected static function _rsortByDesc($a, $b)
{
return self::_sortByDesc($b, $a);
}
/**
* Comparison function for sorting notes by category.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer 1 if note one is greater, -1 if note two is greater; 0
* if they are equal.
*/
protected static function _sortByCategory($a, $b)
{
return strcoll($a['category'] ? $a['category'] : _("Unfiled"),
$b['category'] ? $b['category'] : _("Unfiled"));
}
/**
* Comparison function for reverse sorting notes by category.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer -1 if note one is greater, 1 if note two is greater; 0
* if they are equal.
*/
protected static function _rsortByCategory($a, $b)
{
return self::_sortByCategory($b, $a);
}
/**
* Comparison function for sorting notes by notepad name.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer 1 if note one is greater, -1 if note two is greater;
* 0 if they are equal.
*/
protected static function _sortByNotepad($a, $b)
{
$aowner = $a['memolist_id'];
$bowner = $b['memolist_id'];
$ashare = $GLOBALS['mnemo_shares']->getShare($aowner);
$bshare = $GLOBALS['mnemo_shares']->getShare($bowner);
if ($aowner != $ashare->get('owner')) {
$aowner = $ashare->get('name');
}
if ($bowner != $bshare->get('owner')) {
$bowner = $bshare->get('name');
}
return strcoll($aowner, $bowner);
}
/**
* Comparison function for reverse sorting notes by notepad name.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer -1 if note one is greater, 1 if note two is greater;
* 0 if they are equal.
*/
protected static function _rsortByNotepad($a, $b)
{
return self::_sortByNotepad($b, $a);
}
/**
* Comparison function for sorting notes by modification date.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer 1 if note one is greater, -1 if note two is greater;
* 0 if they are equal.
*/
protected static function _sortByModDate($a, $b)
{
// Get notes` history
$history = $GLOBALS['injector']->getInstance('Horde_History');
$guidA = 'mnemo:' . $a['memolist_id'] . ':' . $a['uid'];
$guidB = 'mnemo:' . $b['memolist_id'] . ':' . $b['uid'];
// Gets the timestamp of the most recent modification to the note
$modDateA = $history->getActionTimestamp($guidA, 'modify');
$modDateB = $history->getActionTimestamp($guidB, 'modify');
// If the note hasn't been modified, get the creation timestamp
if ($modDateA == 0) {
$modDateA = $history->getActionTimestamp($guidA, 'add');
}
if ($modDateB == 0) {
$modDateB = $history->getActionTimestamp($guidB, 'add');
}
if ($modDateA == $modDateB) {
return 0;
}
return ($modDateA > $modDateB) ? 1 : -1;
}
/**
* Comparison function for reverse sorting notes by modification date.
*
* @param array $a Note one.
* @param array $b Note two.
*
* @return integer -1 if note one is greater, 1 if note two is greater,
* 0 if they are equal.
*/
protected static function _rsortByModDate($a, $b)
{
return self::_sortByModDate($b, $a);
}
/**
* Returns the specified permission for the current user.
*
* @param string $permission A permission, currently only 'max_notes'.
*
* @return mixed The value of the specified permission.
*/
public static function hasPermission($permission)
{
global $perms;
if (!$perms->exists('mnemo:' . $permission)) {
return true;
}
$allowed = $perms->getPermissions('mnemo:' . $permission, $GLOBALS['registry']->getAuth());
if (is_array($allowed)) {
switch ($permission) {
case 'max_notes':
$allowed = max($allowed);
break;
}
}
return $allowed;
}
/**
* Returns a note's passphrase for symmetric encryption from the session
* cache.
*
* @param string $id A note id.
*
* @return string The passphrase, if set.
*/
public static function getPassphrase($id)
{
return (strlen($id))
? $GLOBALS['session']->get('mnemo', 'passphrase/' . $id)
: null;
}
/**
* Stores a note's passphrase for symmetric encryption in the session
* cache.
*
* @param string $id A note id.
* @param string $passphrase The note's passphrase.
*
* @return boolean True
*/
public static function storePassphrase($id, $passphrase)
{
global $session;
$session->set('mnemo', 'passphrase/' . $id, $passphrase, $session::ENCRYPT);
}
/**
* Initial app setup code.
*
* Defines the following $GLOBALS (@TODO these should use the injector)
* mnemo_shares
* display_notepads
*/
public static function initialize()
{
$GLOBALS['mnemo_shares'] = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Share')->create();
// Update the preference for which notepads to display. If the
// user doesn't have any selected notepads for view then fall
// back to some available notepad.
$GLOBALS['display_notepads'] = unserialize($GLOBALS['prefs']->getValue('display_notepads'));
if (($notepadId = Horde_Util::getFormData('display_notepad')) !== null) {
if (is_array($notepadId)) {
$GLOBALS['display_notepads'] = $notepadId;
} else {
if (in_array($notepadId, $GLOBALS['display_notepads'])) {
$key = array_search($notepadId, $GLOBALS['display_notepads']);
unset($GLOBALS['display_notepads'][$key]);
} else {
$GLOBALS['display_notepads'][] = $notepadId;
}
}
}
// Make sure all notepads exist now, to save on checking later.
$_temp = ($GLOBALS['display_notepads']) ? $GLOBALS['display_notepads'] : array();
$_all = self::listNotepads();
$GLOBALS['display_notepads'] = array();
foreach ($_temp as $id) {
if (isset($_all[$id])) {
$GLOBALS['display_notepads'][] = $id;
}
}
// All notepads for guests.
if (!count($GLOBALS['display_notepads']) &&
!$GLOBALS['registry']->getAuth()) {
$GLOBALS['display_notepads'] = array_keys($_all);
}
/* If the user doesn't own a notepad, create one. */
$notepads = $GLOBALS['injector']->getInstance('Mnemo_Factory_Notepads')
->create();
if (($new_default = $notepads->ensureDefaultShare()) !== null) {
$GLOBALS['display_notepads'][] = $new_default;
$GLOBALS['prefs']->setValue('default_notepad', $new_default);
}
$GLOBALS['prefs']->setValue('display_notepads', serialize($GLOBALS['display_notepads']));
}
/**
*/
static public function getCssStyle($category)
{
$cManager = new Horde_Prefs_CategoryManager();
$colors = $cManager->colors();
if (!isset($colors[$category])) {
return '';
}
$fgColors = $cManager->fgColors();
return 'color:' . (isset($fgColors[$category]) ? $fgColors[$category] : $fgColors['_default_']) . ';' .
'background:' . $colors[$category] . ';';
}
}
mnemo-4.1.2/locale/bg/LC_MESSAGES/mnemo.mo 0000644 0001750 0001750 00000212361 12233763566 016041 0 ustar jan jan t G \' x4 M y4 4 d 5 5 6 C <7 <