mirror of
https://github.com/nextcloud/documentation.git
synced 2026-01-02 09:49:33 +07:00
removed 5.0 documentation from the 4.5 branch
This commit is contained in:
@@ -1,147 +0,0 @@
|
||||
App config
|
||||
==========
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
define("DEBUG", true);
|
||||
|
||||
$CONFIG = array(
|
||||
/* Flag to indicate ownCloud is successfully installed (true = installed) */
|
||||
"installed" => false,
|
||||
|
||||
/* Type of database, can be sqlite, mysql or pgsql */
|
||||
"dbtype" => "sqlite",
|
||||
|
||||
/* Name of the ownCloud database */
|
||||
"dbname" => "owncloud",
|
||||
|
||||
/* User to access the ownCloud database */
|
||||
"dbuser" => "",
|
||||
|
||||
/* Password to access the ownCloud database */
|
||||
"dbpassword" => "",
|
||||
|
||||
/* Host running the ownCloud database */
|
||||
"dbhost" => "",
|
||||
|
||||
/* Prefix for the ownCloud tables in the database */
|
||||
"dbtableprefix" => "",
|
||||
|
||||
/* Define the salt used to hash the user passwords. All your user passwords are lost if you lose this string. */
|
||||
"passwordsalt" => "",
|
||||
|
||||
/* Force use of HTTPS connection (true = use HTTPS) */
|
||||
"forcessl" => false,
|
||||
|
||||
/* Enhanced auth forces users to enter their password again when performing potential sensitive actions like creating or deleting users */
|
||||
"enhancedauth" => true,
|
||||
|
||||
/* Time in seconds how long an user is authenticated without entering his password again before performing sensitive actions like creating or deleting users etc...*/
|
||||
"enhancedauthtime" => 15 * 60,
|
||||
|
||||
/* Theme to use for ownCloud */
|
||||
"theme" => "",
|
||||
|
||||
/* Path to the 3rdparty directory */
|
||||
"3rdpartyroot" => "",
|
||||
|
||||
/* URL to the 3rdparty directory, as seen by the browser */
|
||||
"3rdpartyurl" => "",
|
||||
|
||||
/* Default app to load on login */
|
||||
"defaultapp" => "files",
|
||||
|
||||
/* Enable the help menu item in the settings */
|
||||
"knowledgebaseenabled" => true,
|
||||
|
||||
/* URL to use for the help page, server should understand OCS */
|
||||
"knowledgebaseurl" => "http://api.apps.owncloud.com/v1",
|
||||
|
||||
/* Enable installing apps from the appstore */
|
||||
"appstoreenabled" => true,
|
||||
|
||||
/* URL of the appstore to use, server should understand OCS */
|
||||
"appstoreurl" => "http://api.apps.owncloud.com/v1",
|
||||
|
||||
/* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
|
||||
"mail_smtpmode" => "sendmail",
|
||||
|
||||
/* Host to use for sending mail, depends on mail_smtpmode if this is used */
|
||||
"mail_smtphost" => "127.0.0.1",
|
||||
|
||||
/* authentication needed to send mail, depends on mail_smtpmode if this is used
|
||||
* (false = disable authentication)
|
||||
*/
|
||||
"mail_smtpauth" => false,
|
||||
|
||||
/* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
|
||||
"mail_smtpname" => "",
|
||||
|
||||
/* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
|
||||
"mail_smtppassword" => "",
|
||||
|
||||
/* Check 3rdparty apps for malicious code fragments */
|
||||
"appcodechecker" => "",
|
||||
|
||||
/* Check if ownCloud is up to date */
|
||||
"updatechecker" => true,
|
||||
|
||||
/* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
|
||||
"log_type" => "owncloud",
|
||||
|
||||
/* File for the owncloud logger to log to, (default is ownloud.log in the data dir */
|
||||
"logfile" => "",
|
||||
|
||||
/* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
|
||||
"loglevel" => "",
|
||||
|
||||
/* Lifetime of the remember login cookie, default is 15 days */
|
||||
"remember_login_cookie_lifetime" => 60*60*24*15,
|
||||
|
||||
/* The directory where the user data is stored, default to data in the owncloud
|
||||
* directory. The sqlite database is also stored here, when sqlite is used.
|
||||
*/
|
||||
// "datadirectory" => "",
|
||||
|
||||
"apps_paths" => array(
|
||||
|
||||
/* Set an array of path for your apps directories
|
||||
key 'path' is for the fs path and the key 'url' is for the http path to your
|
||||
applications paths. 'writable' indicate if the user can install apps in this folder.
|
||||
You must have at least 1 app folder writable or you must set the parameter : appstoreenabled to false
|
||||
*/
|
||||
array(
|
||||
'path'=> '/var/www/owncloud/apps',
|
||||
'url' => '/apps',
|
||||
'writable' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
Using alternative app directories
|
||||
---------------------------------
|
||||
|
||||
ownCloud can be set to use a custom app directory in /config/config.php. Customise the following code and add it to your config file:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'apps_paths' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'path' => OC::$SERVERROOT.'/apps',
|
||||
'url' => '/apps',
|
||||
'writable' => true,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'path' => OC::$SERVERROOT.'/apps2',
|
||||
'url' => '/apps2',
|
||||
'writable' => false,
|
||||
),
|
||||
),
|
||||
|
||||
ownCloud will use the first app directory which it finds in the array with 'writable' set to true.
|
||||
@@ -9,14 +9,7 @@ Contents
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
tutorial
|
||||
templates
|
||||
unittests
|
||||
debugging
|
||||
configfile
|
||||
security
|
||||
vcategories
|
||||
routing
|
||||
apps
|
||||
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
Routing
|
||||
=======
|
||||
|
||||
With routing the request url doesn't need to be matched with a physical file.
|
||||
Instead the url is mapped to a function that handles the request. This way be
|
||||
almost any structure. It can even map different urls to the same function,
|
||||
which is usefull for backward compatibility.
|
||||
|
||||
Last but not least, using routing you only have one place to define the url. So
|
||||
changing the is pretty easy.
|
||||
|
||||
Routing in ownCloud
|
||||
-------------------
|
||||
|
||||
ownCloud uses Symfony Routing Component as its base, look at
|
||||
http://symfony.com/doc/current/book/routing.html for more information.
|
||||
|
||||
Look at the API docs for OC_Router and OC_Route for more information.
|
||||
|
||||
Creating a route
|
||||
----------------
|
||||
|
||||
Application routes are defined in the file routes.php in the appinfo directory.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$this->create('app_script', '/apps/{app}/{file}')
|
||||
->defaults(array('file' => 'index.php'))
|
||||
->requirements(array('file' => '.*.php'))
|
||||
->action('OC', 'loadAppScriptFile');
|
||||
?>
|
||||
|
||||
The first parameter is a friendly name for the route, this can later be used to
|
||||
create a url with this route.
|
||||
|
||||
The second is the url pattern, the placeholders {app} and {file} are used for
|
||||
generating the url and for matching the requested url. The values from the
|
||||
match are supplied to the action function.
|
||||
|
||||
In this example we also define a default for {file} and a requirement. The
|
||||
requirement is used in generating and matching to make sure the correct route
|
||||
is used.
|
||||
|
||||
action function
|
||||
---------------
|
||||
|
||||
The action function is used to specify which function to call when the route
|
||||
matches. This can be a class with function, like in the example, or a callable.
|
||||
|
||||
linkToRoute
|
||||
-----------
|
||||
|
||||
Using a route in php is very simple, just use the linkToRoute.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$url = OC_Helper::linkToRoute( 'download', array('file' => $path));
|
||||
?>
|
||||
|
||||
|
||||
Where 'download' is the route name, and the array are the parameters for the
|
||||
route. If a parameter is not used in the pattern, it will be appended in the
|
||||
query.
|
||||
|
||||
OC.Router.generate
|
||||
------------------
|
||||
|
||||
In javascript it works the same way:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
OC.Router.generate( 'download', { file: path } );
|
||||
|
||||
|
||||
actionInclude
|
||||
-------------
|
||||
|
||||
There is also a helper function to use a php file as an action. Instead of
|
||||
action you use actionInclude('file') and then that file will be included when
|
||||
the route matches. It also adds the parameters from the url to $_GET.
|
||||
|
||||
|
||||
--
|
||||
|
||||
- not depending on filesstructure
|
||||
- URL routing lets you configure an application to accept request URLs that do not map to physical files. Instead, you can use routing to define URLs that are semantically meaningful to users and that can help with search-engine optimization (SEO).
|
||||
|
||||
|
||||
|
||||
Why Do I Use URL Routing? For Ease of Navigation, of course!
|
||||
|
||||
URL Routing, which enables you to change the URL to point to an evaluated expression instead of a fixed file location parameterized with a query string. Why should you care? Read this story and decide for yourself.
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
Security
|
||||
========
|
||||
|
||||
Blacklisted PHP functionality
|
||||
-----------------------------
|
||||
**echo, print(), <?=**
|
||||
Use $this->p in templates instead
|
||||
**error_log**
|
||||
Use throw new Exception("Description") instead
|
||||
**==**
|
||||
Use === instead
|
||||
**!=**
|
||||
Use !== instead
|
||||
**rand(), srand(), mt_rand()**
|
||||
If you need a cryptographical secure random string use OC_Util::generate_random_bytes() instead, the PHP provided functions are `not secure <http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/>`_.
|
||||
|
||||
CSRF protection
|
||||
-----------------------------
|
||||
Please add::
|
||||
|
||||
OC_Util::isCallRegistered()
|
||||
|
||||
or::
|
||||
|
||||
OC_JSON::callCheck() at the top of your file to prevent Cross-site request forgery.
|
||||
|
||||
See http://en.wikipedia.org/wiki/Cross-site_request_forgery
|
||||
|
||||
Auth checks
|
||||
-----------------------------
|
||||
OC_Util::checkLoggedIn() or OC_JSON::checkLoggedIn()
|
||||
Checks if the user is logged in
|
||||
OC_Util::checkAdminUser() or OC_JSON::checkAdminUser()
|
||||
Checks if the user has admin rights
|
||||
OC_Util::checkSubAdminUser() or OC_JSON::checkSubAdminUser()
|
||||
Checks if the user has subadmin rights
|
||||
|
||||
Recommended reading
|
||||
-----------------------------
|
||||
The `OWASP Top Ten Project <https://www.owasp.org/index.php/Top_10_2010-Main>`_ provides good informations about the 10 most common security vulnerabilities in web applications.
|
||||
|
||||
TBD
|
||||
@@ -1,457 +0,0 @@
|
||||
Templates
|
||||
=========
|
||||
.. sectionauthor:: Bernhard Posselt <nukeawhale@gmail.com>
|
||||
|
||||
.. warning::
|
||||
.. versionchanged:: 5.0
|
||||
|
||||
To prevent XSS the following PHP **functions for printing are forbidden: echo, print() and <?=**. Instead use ``p($data)`` for printing your values. Should you require unescaped printing, **double check for XSS** and use: ``print_unescaped($data)``.
|
||||
|
||||
|
||||
.. warning::
|
||||
Templates **must not contain database queries**! All data should be passed to the template via ``$template->assign($key, $value)``.
|
||||
|
||||
|
||||
ownCloud uses its own templating system. Templates reside in the ``template/`` folder. To use them you'll need to instantiate the ``OC_Template`` class with the name of the template. If you want to pass values to it, use the ``assign`` method.
|
||||
|
||||
|
||||
:file:`index.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$allEntries = array('entry1', 'entry2');
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$mainTemplate->assign('entries', $allEntries);
|
||||
$mainTemplate->assign('name', "john doe");
|
||||
$mainTemplate->printPage();
|
||||
?>
|
||||
|
||||
To access the assigned variables in the template, use the $_[] array. The variable will be availabe under the key that you defined (e.g. $_['key']).
|
||||
|
||||
:file:`templates/main.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php foreach($_['entries'] as $entry){ ?>
|
||||
<p><?php p($entry); ?></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
print_unescaped($this->inc('sub.inc'));
|
||||
|
||||
?>
|
||||
|
||||
Templates can also include other templates by using the $this->inc('templateName') method. Use this if you find yourself repeating a lot of the same HTML constructs. The parent variables will also be available in the included templates, but should you require it, you can also pass new variables to it by using the second optional parameter for $this->inc.
|
||||
|
||||
:file:`templates/sub.inc.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<div>I am included but i can still access the parents variables!</div>
|
||||
<?php p($_['name']); ?>
|
||||
|
||||
|
||||
|
||||
OC_Template
|
||||
-----------
|
||||
|
||||
.. php:class:: OC_Template
|
||||
|
||||
|
||||
This class provides the templates for owncloud. It is used for loading template files, assign variables to it and render the whole template.
|
||||
|
||||
.. php:method:: __construct($app, $name[, $renderas])
|
||||
|
||||
:param string $app: the name of the app
|
||||
:param string $file: name of the template file (without suffix)
|
||||
:param string $renderas: If $renderas is set, OC_Template will try to produce a full page in the according layout. For now, renderas can be set to "guest", "user" or "admin"
|
||||
:returns: OC_Template object
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
?>
|
||||
|
||||
|
||||
.. php:method:: addHeader($tag, $attributes[, $text=''])
|
||||
|
||||
:param string $tag: tag name of the element
|
||||
:param array $attributes: array of attrobutes for the element
|
||||
:param string $text: the text content for the element
|
||||
|
||||
Add a custom element to the html <head>
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$mainTemplate->addHeader('title', array(), 'My new Page');
|
||||
?>
|
||||
|
||||
.. php:method:: append($key, $value)
|
||||
|
||||
:param string $key: the key under which the variable can be accessed in the template
|
||||
:param $value: the value that we want to pass
|
||||
:returns: bool
|
||||
|
||||
This function assigns a variable in an array context. If the key already exists, the value will be appended. It can be accessed via $_[$key][$position] in the template.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$customers = array("john", "frank");
|
||||
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$mainTemplate->assign('customers', $customers);
|
||||
$mainTemplate->append('customers', 'hanna');
|
||||
?>
|
||||
|
||||
|
||||
.. php:method:: assign($key, $value[, $sanitizeHTML=true])
|
||||
|
||||
:param string $key: the key under which the variable can be accessed in the template
|
||||
:param $value: the value that we want to pass
|
||||
:param bool $sanitizeHTML: false, if data shouldn't get passed through htmlentities
|
||||
:returns: bool
|
||||
|
||||
This function assigns a variable. It can be accessed via $_[$key] in the template. If the key existed before, it will be overwritten
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$customers = array("john", "frank");
|
||||
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$mainTemplate->assign('customers', $customers);
|
||||
?>
|
||||
|
||||
|
||||
.. php:method:: detectFormfactor()
|
||||
|
||||
:returns: The mode of the client as a string. **default** -> the normal desktop browser interface, **mobile** -> interface for smartphones, **tablet** -> interface for tablets, **standalone** -> the default interface but without header, footer and sidebar, just the application. Useful to use just a specific app on the desktop in a standalone window.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$formFactor = $mainTemplate->detectFormfactor();
|
||||
?>
|
||||
|
||||
|
||||
.. php:method:: fetchPage()
|
||||
|
||||
:returns: the HTML of the template as string
|
||||
|
||||
This function proceeds the template and but prints no output.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. todo:: provide example
|
||||
|
||||
|
||||
.. php:method:: getFormFactorExtension()
|
||||
|
||||
:returns: Returns the formfactor extension for current formfactor (like .mobile or .tablet)
|
||||
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$formFactorExtension = $mainTemplate->detectFormfactorExtension();
|
||||
?>
|
||||
|
||||
|
||||
.. php:method:: inc($file[, $additionalparams])
|
||||
|
||||
:param string $file: the name of the template
|
||||
:param array $additionalparams: an array with additional variables which should be used for the included template
|
||||
:returns: returns content of included template as a string
|
||||
|
||||
Includes another template. use <?php print_unescaped($this->inc('template')); ?> to do this. The included template has access to all parent template variables!
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<div>
|
||||
<?php print_unescaped($this->inc('nav.inc', array('active' => 'nav_entry_1')); ?>
|
||||
</div>
|
||||
|
||||
|
||||
.. php:method:: printPage()
|
||||
|
||||
:returns: true when there is content to print
|
||||
|
||||
This function proceeds the template and prints its output.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$mainTemplate = new OC_Template('news', 'main', 'user');
|
||||
$mainTemplate->assign('test', array("test", "test2"));
|
||||
$mainTemplate->printPage();
|
||||
?>
|
||||
|
||||
.. php:method:: printAdminPage($application, $name[, $parameters])
|
||||
|
||||
:param string $application: The application we render the template for
|
||||
:param string $name: Name of the template
|
||||
:param array $parameters: Parameters for the template
|
||||
:returns: bool
|
||||
|
||||
Shortcut to print a simple page for admin
|
||||
|
||||
**Example:**
|
||||
|
||||
.. todo:: provide example
|
||||
|
||||
|
||||
.. php:method:: printGuestPage($application, $name[, $parameters])
|
||||
|
||||
:param string $application: The application we render the template for
|
||||
:param string $name: Name of the template
|
||||
:param array $parameters: Parameters for the template
|
||||
:returns: bool
|
||||
|
||||
Shortcut to print a simple page for guests
|
||||
|
||||
**Example:**
|
||||
|
||||
.. todo:: provide example
|
||||
|
||||
|
||||
.. php:method:: printUserPage($application, $name[, $parameters])
|
||||
|
||||
:param string $application: The application we render the template for
|
||||
:param string $name: Name of the template
|
||||
:param array $parameters: Parameters for the template
|
||||
:returns: bool
|
||||
|
||||
Shortcut to print a simple page for users
|
||||
|
||||
**Example:**
|
||||
|
||||
.. todo:: provide example
|
||||
|
||||
|
||||
|
||||
Template functions
|
||||
------------------
|
||||
|
||||
These functions are automatically available in all templates.
|
||||
|
||||
html_select_options
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
.. php:function:: html_select_options($options, $selected[, $params])
|
||||
|
||||
:param array $options: an array of the form value => label
|
||||
:param string/array $selected: an array containing strings or a simple string which sets a value as selected
|
||||
:param array $params: optional parameters that are done in key => value
|
||||
:returns: the html as string of preset <option> tags
|
||||
|
||||
.. todo:: Fix parameters and add example
|
||||
|
||||
|
||||
|
||||
human_file_size
|
||||
~~~~~~~~~~~~~~~
|
||||
.. php:function:: human_file_size($bytes)
|
||||
|
||||
:param int $bytes: the bytes that we want to convert to a more readable format
|
||||
:returns: the human readable size as string
|
||||
|
||||
Turns bytes into human readable formats, for instance 1024 bytes get turned into 1kb, 1024*1024 bytes get turned into 1mb
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// this would print <li>2kB</li>
|
||||
?>
|
||||
<li><?php p($this->human_file_size('2048')); ?></li>
|
||||
|
||||
|
||||
|
||||
image_path
|
||||
~~~~~~~~~~
|
||||
.. php:function:: image_path($app, $image)
|
||||
|
||||
:param string $app: the name of your app as a string. If the string is empty, ownCloud looks for the image in core
|
||||
:param array $image: the filename of the image
|
||||
:returns: the absolute URL to the image as a string
|
||||
|
||||
This function looks up images in several common directories and returns the full link to it. The following directories are being searched:
|
||||
|
||||
- /themes/$theme/apps/$app/img/$image
|
||||
- /themes/$theme/$app/img/$image
|
||||
- /$app/img/$image
|
||||
|
||||
When you pass an empty string for $app, the following directories will be searched:
|
||||
|
||||
- /themes/$theme/apps/$app/img/$image
|
||||
- /themes/$theme/core/img/$image
|
||||
- /core/img/$image
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<img src="<?php print_unescaped(
|
||||
image_path('news', 'starred.svg');
|
||||
); ?>" />
|
||||
|
||||
|
||||
|
||||
|
||||
link_to
|
||||
~~~~~~~
|
||||
.. php:function:: link_to($app, $file, [$args])
|
||||
|
||||
:param string $app: the name of your app as a string. If the string is empty, ownCloud asumes that the file is in /core/
|
||||
:param string $file: the relative path from your apps root to the file you want to access
|
||||
:param array $args: the GET parameters that you want set in the URL in form key => value. The value will be run through urlencode()
|
||||
:returns: the absolute URL to the file
|
||||
|
||||
This function is used to produce generate clean and absolute links to your files or pages.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// this will produce the link:
|
||||
// index.php/news/pages/weather.php?show=berlin
|
||||
?>
|
||||
<ul>
|
||||
<li><a href="<?php
|
||||
print_unescaped(
|
||||
link_to('news', 'pages/weather.php', array("show" => "berlin"));
|
||||
);
|
||||
?>">Show Weather for Berlin</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
mimetype_icon
|
||||
~~~~~~~~~~~~~
|
||||
.. php:function:: mimetype_icon($mimetype)
|
||||
|
||||
:param array $mimetype: the mimetype for which we want to look up the icon
|
||||
:returns: the absolute URL to the icon
|
||||
|
||||
A shortcut for getting a mimetype icon.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<img src="<?php print_unescaped(
|
||||
mimetype_icon('application/xml');
|
||||
); ?>" />
|
||||
|
||||
|
||||
|
||||
p
|
||||
~
|
||||
.. php:function:: p($data)
|
||||
|
||||
:param $data: the variable/array/object that should be printed
|
||||
|
||||
.. versionadded:: 5.0
|
||||
|
||||
This is the print statement which prints out XSS escaped values. ownCloud does not allow the direct usage of echo or print but enforces wrapper functions to prevent unwanted XSS vulnerabilities. If you want to print unescaped data, look at print_unescaped
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php $names = array("John", "Jakob", "Tom"); ?>
|
||||
<div>
|
||||
<ul>
|
||||
<?php foreach($names as $name){ ?>
|
||||
<li><?php p($name); ?></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
print_unescaped
|
||||
~~~~~~~~~~~~~~~
|
||||
.. php:function:: print_unescaped($data)
|
||||
|
||||
:param $data: the variable/array/object that should be printed
|
||||
|
||||
.. versionadded:: 5.0
|
||||
|
||||
This function does not escape the content for XSS. This would typically be used to print HTML or JavaScript that is generated by the server and **checked for XSS** vulnerabilities.
|
||||
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php $html = "<div>Some HTML</div>"; ?>
|
||||
<div>
|
||||
<?php print_unescaped($html); ?>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
relative_modified_date
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. php:function:: relative_modified_date($timestamp)
|
||||
|
||||
:param int $timestamp: the timestamp from whom we compute the time span until now
|
||||
:returns: a relative date as string
|
||||
|
||||
Instead of displaying a date, it is often better to give a relative date like: "2 days ago" or "3 hours ago". This function turns a timestamp into a relative date.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// this would print <span>5 minutes ago</span>
|
||||
?>
|
||||
<span><?php p(relative_modified_date('29393992912')); ?></span>
|
||||
|
||||
|
||||
|
||||
simple_file_size
|
||||
~~~~~~~~~~~~~~~~
|
||||
.. php:function:: simple_file_size($bytes)
|
||||
|
||||
:param int $bytes: the bytes that we want to convert to a more readable format in megabytes
|
||||
:returns: the human readable size as string
|
||||
|
||||
A more simpler function that only turns bytes into megabytes. If its smaller than 0.1 megabytes, < 0.1 is being returned. If its bigger than 1000 megabytes, > 1000 is being returned.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// this would print <li>< 0.1</li>
|
||||
?>
|
||||
<li><?php p(simple_file_size('2048')); ?></li>
|
||||
|
||||
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
- http://en.wikipedia.org/wiki/Cross-site_scripting
|
||||
- https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
|
||||
- https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
|
||||
@@ -1,436 +0,0 @@
|
||||
App Tutorial
|
||||
============
|
||||
|
||||
.. sectionauthor:: Bernhard Posselt <nukeawhale@gmail.com>
|
||||
|
||||
Before you start, please check if there already is a `similar app <http://apps.owncloud.com>`_ you could contribute to. Also, feel free to communicate your idea and plans to the `mailing list <https://mail.kde.org/mailman/listinfo/owncloud>`_ so other contributors might join in.
|
||||
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
To get started you'll need to clone the basic git repositories into your web directory. Depending on your distro this will either be :file:`/var/www or` :file:`/srv/http`
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo chmod a+rw /var/www # only do this on your dev machine!
|
||||
cd /var/www
|
||||
git clone https://github.com/owncloud/core.git owncloud
|
||||
git clone https://github.com/owncloud/apps.git apps
|
||||
git clone https://github.com/owncloud/3rdparty.git 3rdparty
|
||||
|
||||
Now restart your apache server and get ready to set up owncloud at http://localhost/owncloud
|
||||
|
||||
|
||||
Enable debugging mode
|
||||
---------------------
|
||||
To disable JavaScript and CSS caching you'll have to turn on debugging in :file:`/var/www/owncloud/config/config.php` by adding this to the end of the file::
|
||||
|
||||
DEFINE('DEBUG', true);
|
||||
|
||||
|
||||
Create your app
|
||||
---------------
|
||||
The best way to create your application is to simply modify the apptemplate app.
|
||||
|
||||
To do that execute:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd /var/www/apps
|
||||
sudo cp -r apptemplate yourappname
|
||||
sudo chown -R youruser:yourgroup yourappname
|
||||
|
||||
To enable your app, simply link it into the apps directory:
|
||||
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ln -s /var/www/apps/yourappname /var/www/owncloud/apps/yourappname
|
||||
|
||||
or create a second apps directory in your :file:`/var/www/owncloud/config/config.php` (see :doc:`configfile`)
|
||||
|
||||
**Don't forget to enable it on the apps settings page!**
|
||||
|
||||
Now change into your app directory::
|
||||
|
||||
cd /var/www/apps/yourappname
|
||||
|
||||
|
||||
Adjust apptemplate
|
||||
------------------------------------------
|
||||
Certain things are still apptemplate specific and you will have to convert them to match your app.
|
||||
|
||||
.. todo::
|
||||
|
||||
Provide some sed commands for simple transformation
|
||||
|
||||
The following things will need to be changed:
|
||||
|
||||
* AGPL Header: author and copyright
|
||||
* **\\OC_App::getAppPath('apptemplate')** to **\\OC_App::getAppPath('yourappname')**
|
||||
* **namespace OCA\\AppTemplate** to **namespace OCA\\YourAppName**
|
||||
* The Classpaths in :file:`appinfo/bootstrap.php`
|
||||
|
||||
|
||||
App information
|
||||
---------------
|
||||
You'll need to give some information on your app for instance the name. To do that open the :file:`appinfo/app.php` and adjust it like this
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
require_once \OC_App::getAppPath('yourappname') . '/appinfo/bootstrap.php';
|
||||
|
||||
\OCP\App::addNavigationEntry( array(
|
||||
|
||||
// the string under which your app will be referenced
|
||||
// in owncloud, for instance: \OC_App::getAppPath('APP_ID')
|
||||
'id' => 'yourappname',
|
||||
|
||||
// sorting weight for the navigation. The higher the number, the higher
|
||||
// it will be listed in the navigation
|
||||
'order' => 74,
|
||||
|
||||
// the route that will be shown on startup
|
||||
'href' => \OC_Helper::linkToRoute('yourappname_index'),
|
||||
|
||||
// the icon that will be shown in the navigation
|
||||
'icon' => \OCP\Util::imagePath('yourappname', 'example.png' ),
|
||||
|
||||
// the title of your application. This will be used in the
|
||||
// navigation or on the settings page of your app
|
||||
'name' => \OC_L10N::get('yourappname')->t('Your App')
|
||||
|
||||
));
|
||||
|
||||
?>
|
||||
|
||||
The second place where app specifc information is stored is in :file:`appinfo/info.xml`
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>yourappname</id>
|
||||
<name>Your App</name>
|
||||
<description>Your App description</description>
|
||||
<version>1.0</version>
|
||||
<licence>AGPL</licence>
|
||||
<author>Your Name</author>
|
||||
<require>4</require>
|
||||
</info>
|
||||
|
||||
|
||||
Classloader
|
||||
-----------
|
||||
The classloader is configured in :file:`appinfo/bootstrap.php`. The classloader frees you from requiring your classes when you use them. If a class is used and its not yet available, the loader will automatically include the needed file.
|
||||
|
||||
To add a class to the classloader, simply use something like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// loads the class MyClass from the file folder/myclass.php
|
||||
\OC::$CLASSPATH['OCA\YourAppName\MyClass'] = 'apps/yourappname/folder/myclass.php';
|
||||
?>
|
||||
|
||||
|
||||
Dependency Injection
|
||||
--------------------
|
||||
Dependency Injection helps you to create testable code. A good overview over how it works and what the benefits are can be seen on `Google's Clean Code Talks <http://www.youtube.com/watch?v=RlfLCWKxHJ0>`_
|
||||
|
||||
The container is configured in :file:`appinfo/bootstrap.php`. We use Pimple for the container. The documentation on how to use it can be seen on the `Pimple Homepage <http://pimple.sensiolabs.org/>`_
|
||||
|
||||
To add your own class simply add a new line inside the **createDIContainer** function:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
$container['MyClass'] = function($c){
|
||||
return new MyClass($c['SomeOtherClass']);
|
||||
};
|
||||
|
||||
?>
|
||||
|
||||
|
||||
|
||||
Controllers
|
||||
-----------
|
||||
The App Template provides a simple baseclass for adding controllers. Controllers connect your view (templates) with your database. Controllers themselves are connected to one or more routes.
|
||||
|
||||
The apptemplate comes with several different controllers. A simple controller would look like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
namespace OCA\YourApp;
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request: an instance of the request
|
||||
* @param API $api: an api wrapper instance
|
||||
*/
|
||||
public function __construct($api, $request){
|
||||
parent::__construct($api, $request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief sets a global system value
|
||||
* @param array $urlParams: an array with the values, which were matched in
|
||||
* the routes file
|
||||
*/
|
||||
public function myControllerMethod($urlParams=array()){
|
||||
$value = $this->params('somesetting');
|
||||
|
||||
$response = new JSONResponse($this->appName);
|
||||
$response->setParams(array('value' => $value));
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
An instance of the api is passed via dependency injection, the same goes for a Request instance. POST and GET parameters are abstracted by the Request class and can be accessed via **$this->params('myPostOrGetKey')** inside the controller. This has been done to make the app better testable.
|
||||
|
||||
.. note:: If a POST and GET value exist with the same key, the POST value is preferred. You should avoid to have both values with the same key though.
|
||||
|
||||
Every controller method has to return a response. All possible reponses can be found in :file:`lib/response.php`. The file contains wrappers for Ownclouds internal template engine and JSON response and is used to create a uniform response object which is testable.
|
||||
|
||||
Don't forget to add your controller to the dependency container in :file:`appinfo/bootstrap.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// in the createDIContainer function
|
||||
|
||||
$container['MyController'] = function($c){
|
||||
return new MyController($c['API'], $c['Request']);
|
||||
};
|
||||
|
||||
?>
|
||||
|
||||
and to the classloader
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
\OC::$CLASSPATH['OCA\YourAppName\MyController'] = 'apps/yourappname/controllers/my.controller.php';
|
||||
?>
|
||||
|
||||
|
||||
Database Access
|
||||
---------------
|
||||
ownCloud uses a database abstraction layer on top of either MDB2 or PDO, depending on the availability of PDO on the server.
|
||||
|
||||
Apps should always use prepared statements when accessing the database as seen in the following example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$userId = 'tom';
|
||||
$query = \OC_DB::prepare("SELECT * FROM *PREFIX*mytable WHERE user = ?");
|
||||
$result = $query->execute(array($userId));
|
||||
$data = $result->fetchAll();
|
||||
?>
|
||||
|
||||
|
||||
'*PREFIX*' in the query string will be replaced by the configured database table prefix while preparing the query. Arguments for the prepared statement are denoted by a '?' in the query string and passed during execution in an array.
|
||||
|
||||
For more information about MDB2 style prepared statements, please see the `official MDB2 documentation <http://pear.php.net/package/MDB2/docs>`_
|
||||
|
||||
If an app requires additional tables in the database they can be automatically created and updated by specifying them inside :file:`appinfo/database.xml` using MDB2's xml scheme notation where the placeholders '*dbprefix*' and '*dbname*' can be used for the configured database table prefix and database name.
|
||||
|
||||
An example database XML file would look like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<database>
|
||||
<name>*dbname*</name>
|
||||
<create>true</create>
|
||||
<overwrite>false</overwrite>
|
||||
<charset>utf8</charset>
|
||||
<table>
|
||||
<name>*dbprefix*yourapp_items</name>
|
||||
<declaration>
|
||||
<field>
|
||||
<name>item_id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>4</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>uid_owner</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>item_name</name>
|
||||
<type>text</type>
|
||||
<notnull>true</notnull>
|
||||
<length>100</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>item_path</name>
|
||||
<type>clob</type>
|
||||
<notnull>true</notnull>
|
||||
</field>
|
||||
</declaration>
|
||||
</table>
|
||||
</database>
|
||||
|
||||
|
||||
To update the tables used by the app, simply adjust the database.xml file and increase the app version number in :file:`appinfo/version` to trigger an update.
|
||||
|
||||
|
||||
|
||||
Routes
|
||||
------
|
||||
Routing connects your URL with your controller methods and allows you to create constant and nice URLs. Its also easy to extract values from the URL.
|
||||
|
||||
Owncloud uses `Symphony Routing <http://symfony.com/doc/2.0/book/routing.html>`_
|
||||
|
||||
Routes are declared in :file:`appinfo/routes.php`
|
||||
|
||||
A simple route would look like this:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$this->create('yourappname_routename', '/myurl/{value}')->action(
|
||||
function($params){
|
||||
callController('MyController', 'methodName', $params);
|
||||
}
|
||||
);
|
||||
?>
|
||||
|
||||
The first argument is the name of your route. This is used to get the URL of the route, for instance in your Javascript code.
|
||||
|
||||
The second parameter is the URL which should be matched. You can extract values from the URL by using **{KEY}** in the section that you want to get. That value is then available under **$params['KEY']**, for the above example it would be **$params['value']**.
|
||||
|
||||
The $params array is always passed to your controllermethod as the only parameter.
|
||||
|
||||
You can also limit the route to GET or POST requests by simply adding ->post() or ->get() before the action method like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$this->create('yourappname_routename', '/myurl/{value}')->post()->action(
|
||||
function($params){
|
||||
callAjaxController('MyController', 'methodName', $params);
|
||||
}
|
||||
);
|
||||
?>
|
||||
|
||||
.. warning:: Dont forget to use callAjaxController() for Ajax requests!
|
||||
|
||||
In JavaScript you can call the routes like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var params = {value: 'hi'};
|
||||
var url = OC.Router.generate('yourappname_routename', params);
|
||||
|
||||
.. note:: Be sure to only use the routes generator after the routes are loaded. This can be done by registering a callback with OC.Router.registerLoadedCallback(callback)
|
||||
|
||||
You can also omit the second generate function parameter if you dont extract any values from the URL at all.
|
||||
|
||||
|
||||
**See also:** :doc:`routing`
|
||||
|
||||
|
||||
API abstraction layer
|
||||
---------------------
|
||||
Owncloud currently has a ton of static methods which is a very bad thing concerning testability. Therefore the app template comes with an api abstraction layer which is located at :file:`lib/api.php`.
|
||||
|
||||
If you find yourself in need to use more Owncloud internal static methods, add them to the api layer by simply creating a new method for each of them, like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// inside the API class
|
||||
|
||||
public function methodName($someParam){
|
||||
\OCP\Util::methodName($this->appName, $someParam);
|
||||
}
|
||||
?>
|
||||
|
||||
This will allow you to easily mock the API in your unittests.
|
||||
|
||||
.. note:: This will eventually be replaced with an internal Owncloud API layer.
|
||||
|
||||
|
||||
Templates
|
||||
---------
|
||||
Templates reside in the **template/** folder. To use them in your controller, use the TemplateResponse class, for instance
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// in your controller
|
||||
|
||||
public function index($urlParams=array()){
|
||||
|
||||
// main is the template name. Owncloud will look for template/main.php
|
||||
$response = new TemplateResponse($this->appName, 'main');
|
||||
|
||||
$params = array('templateVar' => 1);
|
||||
$response->setParams($params);
|
||||
|
||||
return $response;
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
**For more info, see** :doc:`templates`
|
||||
|
||||
JavaScript and CSS
|
||||
------------------
|
||||
JavaScript files go to the **js/** directory, CSS files to the **css/** directory. They are both minified in production and must therefore be declared in your controller method.
|
||||
|
||||
To add a script in your controller method, use the controller's **addScript** and **addStyle** methods.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// in your controller
|
||||
public function index($urlParams=array()){
|
||||
|
||||
// adds the js/admin.js file
|
||||
$this->api->addScript('admin');
|
||||
|
||||
// adds the css/admin.css file
|
||||
$this->api->addStyle('admin');
|
||||
|
||||
// etc
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
If you have to include an image in your CSS, use %appswebroot% and %webroot% for creating absolute paths to your image, for instance:
|
||||
|
||||
|
||||
.. code-block:: css
|
||||
|
||||
.folder > .title {
|
||||
background-image: url('%webroot%/core/img/places/folder.svg');
|
||||
}
|
||||
|
||||
|
||||
Publish your app
|
||||
----------------
|
||||
At `apps.owncloud.com <https://apps.owncloud.com>`_ for other ownCloud users
|
||||
@@ -1,98 +0,0 @@
|
||||
Unittests
|
||||
=========
|
||||
|
||||
Getting PHPUnit
|
||||
---------------
|
||||
|
||||
Owncloud uses PHPUnit for tests. To install it, either get it via your packagemanager::
|
||||
|
||||
sudo apt-get install phpunit
|
||||
|
||||
or install it via PEAR::
|
||||
|
||||
pear config-set auto_discover 1
|
||||
pear install pear.phpunit.de/PHPUnit
|
||||
|
||||
After the installation the ''phpunit'' command is available.
|
||||
|
||||
Writing unittests
|
||||
-----------------
|
||||
|
||||
To get started, do the following:
|
||||
- Create a directory called ``tests`` in the top level of your application
|
||||
- Create a php file in the directory and ``require_once`` your class which you want to test.
|
||||
|
||||
Then you can simply run the created test with phpunit.
|
||||
|
||||
.. note:: If you use owncloud functions in your class under test (i.e: OC::getUser()) you'll need to bootstrap owncloud or use dependency injection.
|
||||
|
||||
.. note:: You'll most likely run your tests under a different user than the webserver. This might cause problems with your PHP settings (i.e: open_basedir) and requires you to adjust your configuration.
|
||||
|
||||
An example for a simple test would be:
|
||||
|
||||
:file:`/srv/http/owncloud/apps/myapp/tests/testsuite.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
require_once("../myfolder/myfunction.php");
|
||||
|
||||
class TestAddTwo extends PHPUnit_Framework_TestCase {
|
||||
|
||||
public function testAddTwo(){
|
||||
$this->assertEquals(5, addTwo(3));
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
:file:`/srv/http/owncloud/apps/myapp/tests/testsuite.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
function addTwo($number){
|
||||
return $number + 2;
|
||||
}
|
||||
?>
|
||||
|
||||
In :file:`/srv/http/owncloud/apps/myapp/` you run the test with::
|
||||
|
||||
phpunit tests/testsuite.php
|
||||
|
||||
|
||||
For more resources on PHPUnit visit: http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html
|
||||
|
||||
Bootstrapping Owncloud
|
||||
----------------------
|
||||
If you use Owncloud functions or classes in your code, you'll need to make them available to your test by bootstrapping Owncloud.
|
||||
|
||||
To do this, you'll need to provide the ``--bootstrap`` argument when running PHPUnit
|
||||
|
||||
:file:`/srv/http/owncloud`::
|
||||
|
||||
phpunit --bootstrap tests/bootstrap.php apps/myapp/tests/testsuite.php
|
||||
|
||||
If you run the test under a different user than your webserver, you'll have to
|
||||
adjust your php.ini and file rights.
|
||||
|
||||
:file:`/etc/php/php.ini`::
|
||||
|
||||
open_basedir = none
|
||||
|
||||
:file:`/srv/http/owncloud`::
|
||||
|
||||
su -c "chmod a+r config/config.php"
|
||||
su -c "chmod a+rx data/"
|
||||
su -c "chmod a+w data/owncloud.log"
|
||||
|
||||
Dependency Injection
|
||||
--------------------
|
||||
Yet to be decided
|
||||
|
||||
Further Reading
|
||||
---------------
|
||||
- http://googletesting.blogspot.de/2008/08/by-miko-hevery-so-you-decided-to.html
|
||||
- http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html
|
||||
- http://www.youtube.com/watch?v=4E4672CS58Q&feature=bf_prev&list=PLBDAB2BA83BB6588E
|
||||
- Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin)
|
||||
@@ -1,120 +0,0 @@
|
||||
Categories API
|
||||
==============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
.. sectionauthor:: Thomas Tanghus <thomas@tanghus.net>
|
||||
|
||||
The Categories API is as the name says used for categorizing objects. The visual representation can be different for each app and is totally up to the developer/designer: you can add tags like for example used in `github issues <https://github.com/owncloud/core/issues/>`_ , you can show your objects in a (one-level) hierarchy or you can simply use comma-separated strings.
|
||||
|
||||
The API is mainly designed for objects using `vCard`_ or `iCalendar <https://en.wikipedia.org/wiki/ICalendar>`_ as storage, as they all have a CATEGORIES property from which the categories are extracted, and were they will be saved so that client apps like Apples `iCal <https://en.wikipedia.org/wiki/ICal>`_ and `KDEs Kontact <http://userbase.kde.org/Kontact>`_ can use them as well. Currently the API is used in the Calendar, Task and Contacts apps, plus recently the 3rd party Journal app.
|
||||
|
||||
Internally the categories and the object/category relations are stored using the category, the user ID, the object ID and a type identifier to be able uniquely identify where a category "belongs to". The types are similar to the types used in the `Share API <http://owncloud.org/dev/apps/share-api/>`_ for example `contact`, `event` or `task`.
|
||||
|
||||
Besides being used for categories, the API also supports setting objects as favorites. Favorites are simply a separate category internally, but convenience methods for getting/setting objects as favorites are available.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The API can be used both from PHP and via a simple Javascript object.
|
||||
|
||||
PHP
|
||||
---
|
||||
|
||||
As example I will use a very simplified version of how it is used in the Contacts app. The real implementation is optimized for speed and low memory consumption, but there's no need to show that here.
|
||||
|
||||
First check if any categories have been saved for `contact` objects, if not scan all vCards for categories:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
if(\OC_VCategories::isEmpty('contact')) {
|
||||
$categorymgr = new \OC_VCategories('contact');
|
||||
$cards = array();
|
||||
foreach(VCard::all() as $contact) {
|
||||
$cards[] = array($contact['id'], $contact['carddata']);
|
||||
}
|
||||
$categorymgr->rescan($cards, true);
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
Here we first create an instance of OC_VCategories and tell it to store categories identified by ``contact`` type. Then we fetch all the contacts and create and array holding arrays of id/carddata [1]_ pairs. The OC_VCategories object is then told to scan all the vCards ``CATEGORIES`` property and save the result when done. If it finds any categories it doesn't know already, they will be added to the database (category names are NOT case-sensitive). Additionally it will create relations between the category and the contact object to be used by the contacts app. The ``rescan`` method also takes a third boolean argument ``reset`` which will purge any categories and relations for the current user.
|
||||
|
||||
This piece of code will in most cases only run once i.e. when the user first opens the Contacts app after upgrade to ownCloud 5. Behind the scene any update or additions will scan for categories using the methods ``loadFromVObject(int $id, OC_VObject $vobject)`` which scans an already parsed VCALENDAR, VEVENT, VTODO, VJOURNAL or as in this example VCARD (if given a VCALENDAR the class will use the first found of either VEVENT, VTODO or VJOURNAL). Similarly when a contact is deleted the ``purgeObject($id)`` method will remove any category/object relations. When a user is deleted all entries for that user will automatically be purged from the database as well.
|
||||
|
||||
**Instantiation**
|
||||
|
||||
In the example above the most basic instantiation is shown. It assumes that the user is the currently logged in user, and has no default values. Most apps will want to provide some basic values to use if none are extracted or if the app doesn't use VEVENT, VTODO, VJOURNAL or VCARD as storage.
|
||||
Default values can be given in the constructor:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$defcategories = array('Friends', 'Family', 'Work', 'Other');
|
||||
$categorymgr = new \OC_VCategories('contact', null, $defcategories);
|
||||
?>
|
||||
|
||||
The second argument being null will use the current user id. After instantiating this way the database will be pre-filled with the default categories for the current user, and any ``isEmpty()`` calls will of course return **false** ;)
|
||||
|
||||
For acting on user input the following methods, which should be mostly self-explanatory, are available:
|
||||
|
||||
.. php:class:: OC_VCategories
|
||||
|
||||
.. php:method:: __construct()
|
||||
|
||||
.. todo:: add constructor doc
|
||||
|
||||
.. php:method:: add($name)
|
||||
|
||||
:param string $name:
|
||||
:returns: the integer id of the new category or **false** if it already exists.
|
||||
|
||||
|
||||
.. php:method:: delete($names, array &$objects=null)
|
||||
|
||||
:param string $names: deletes the categories in the array `$names` and any object/category/user relations saved.
|
||||
:param array $objects: If `$objects` is not null it is assumed to be an array of id/data pairs passed by reference.
|
||||
:returns: the integer id of the new category or **false** if it already exists.
|
||||
|
||||
The data is parsed into an OC_VObject and if found the categories will be removed from the CATEGORIES property and the OC_VObject will be serialized back to a string again. It is up to the app to store the data afterwards.
|
||||
|
||||
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function hasCategory($name); //boolean
|
||||
|
||||
public function addToCategory($objid, $category, $type = null);
|
||||
public function removeFromCategory($objid, $category, $type = null);
|
||||
|
||||
`addToCategory()` creates an user/category/object relation. `$category` can be either an integer category id or a string with the category name. If `$type` is null the type provided in the constructor will be used.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function categories($format = null);
|
||||
|
||||
Per default this returns an array of the category names, but given the `$format` argument `OC_VCategories::FORMAT_MAP`, it will return an array of `array('id' => $id, 'name' => $name)` maps.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function idsForCategory($category);
|
||||
|
||||
Returns an array of integer object ids. `$category` can again be either the integer category id or a string with the name.
|
||||
|
||||
Favorites
|
||||
---------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function addToFavorites($objid, $type = null);
|
||||
public function removeFromFavorites($objid, $type = null);
|
||||
public function getFavorites($type = null);
|
||||
|
||||
Javascript
|
||||
----------
|
||||
|
||||
To be written...
|
||||
|
||||
.. [1] An example of a `vCard <https://en.wikipedia.org/wiki/Vcard#vCard_3.0>`_ version 3.0
|
||||
Reference in New Issue
Block a user