Revert "Document OCSResponse + Controller, StreamResponse usage and Database layer cleanup & deprecation"

This commit is contained in:
Bernhard Posselt
2015-03-20 12:57:37 +01:00
parent 91213e6425
commit 617a52dd46
5 changed files with 138 additions and 184 deletions

View File

@@ -4,39 +4,27 @@ Changelog
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
The following changes went into ownCloud 8.1:
The following changes went into ownCloud 8:
Breaking changes
================
None so far
Features
========
* There is a new :doc:`OCSResponse and OCSController <controllers>` which allows you to easily migrate OCS code to the App Framework. This was added purely for compatibility reasons and the preferred way of doing APIs is using a :doc:`api`
* You can now stream files in PHP by using the built in :doc:`StreamResponse <controllers>`.
* For more advanced usecases you can now implement the :doc:`CallbackResponse <controllers>` interface which allows your response to do its own response rendering
* In addition to passing an array of positional parameters using execute on a mapper method you can now :doc:`pass an associative array <database>` to use named parameters in SQL queries
* Setting session variables inside a controller requires the **@UseSession** annotation, otherwise the session will be closed
* Applications not using the AppFramework need now to register their routes as well in **appinfo/routes.php**. See https://mailman.owncloud.org/pipermail/devel/2014-August/000565.html
Deprecations
============
This is a deprecation roadmap which lists all current deprecation targets and will be updated from release to release:
.. note:: Deprecations on interfaces also affect the implementing classes!
10.0
----
* **OCP\\IDb**: This interface and the implementing classes will be removed in favor of **OCP\\IDbConnection**. Various layers in between have also been removed to be consistent with the PDO classes. This leads to the following changes:
* `OCP\\AppFramework\\IApi <https://github.com/owncloud/core/blob/d59c4e832fea87d03d199a3211186a47fd252c32/lib/public/appframework/iapi.php>`_: full class. Removal planned in **8.3**
* `OCP\\AppFramework\\IAppContainer <https://github.com/owncloud/core/blob/d59c4e832fea87d03d199a3211186a47fd252c32/lib/public/appframework/iappcontainer.php>`_: methods **getCoreApi** and **log**. Removal planned in **8.3**
* `OCP\\AppFramework\\Controller <https://github.com/owncloud/core/blob/d59c4e832fea87d03d199a3211186a47fd252c32/lib/public/appframework/controller.php>`_: methods **params**, **getParams**, **method**, **getUploadedFile**, **env**, **cookie**, **render**. Removal planned in **8.3**
* Replace all calls on the db using **getInsertId** with **lastInsertId**
* Replace all calls on the db using **prepareQuery** with **prepare**
* The **__construct** method of **OCP\\AppFramework\\Db\\Mapper** no longer requires an instance of **OCP\\IDb** but an instance of **OCP\\IDbConnection**
* The **execute** method on **OCP\\AppFramework\\Db\\Mapper** no longer returns an instance of **OC_DB_StatementWrapper** but an instance of **PDOStatement**, so the following methods called on the result will no longer work: **fetchRow**, **fetchOne**, **bindParam**. Simply migrate those to their PDO equivalents.
.. note:: Deprecations of constants and methods with namespaces!
9.0
---
* The following methods have been moved into the **OCP\\Template::<method>** class instead of being namespaced directly:
* The following methods have been moved into the **OCP\\Template::<method>** class instead of being namespaced directly, Removal planned in **9.0**:
* **OCP\\image_path**
* **OCP\\mimetype_icon**
@@ -46,12 +34,23 @@ This is a deprecation roadmap which lists all current deprecation targets and wi
* **OCP\\relative_modified_date**
* **OCP\\html_select_options**
* **OCP\\simple_file_size** has been deprecated in favour of **OCP\\Template::human_file_size**
* The **OCP\\PERMISSION_<permission>** and **OCP\\FILENAME_INVALID_CHARS** have been moved to **OCP\\Constants::<old name>**
* The **OC_GROUP_BACKEND_<method>** and **OC_USER_BACKEND_<method>** have been moved to **OC_Group_Backend::<method>** and **OC_User_Backend::<method>** respectively
* **OCP\\simple_file_size** has been deprecated in favour of **OCP\\Template::human_file_size**. Removal planned in **9.0**
* The **OCP\\PERMISSION_<permission>** and **OCP\\FILENAME_INVALID_CHARS** have been moved to **OCP\\Constants::<old name>**. Removal planned in **9.0**
* The **OC_GROUP_BACKEND_<method>** and **OC_USER_BACKEND_<method>** have been moved to **OC_Group_Backend::<method>** and **OC_User_Backend::<method>** respectively. Removal planned in **9.0**
8.3
---
* `OCP\\AppFramework\\IApi <https://github.com/owncloud/core/blob/d59c4e832fea87d03d199a3211186a47fd252c32/lib/public/appframework/iapi.php>`_: full class
* `OCP\\AppFramework\\IAppContainer <https://github.com/owncloud/core/blob/d59c4e832fea87d03d199a3211186a47fd252c32/lib/public/appframework/iappcontainer.php>`_: methods **getCoreApi** and **log**
* `OCP\\AppFramework\\Controller <https://github.com/owncloud/core/blob/d59c4e832fea87d03d199a3211186a47fd252c32/lib/public/appframework/controller.php>`_: methods **params**, **getParams**, **method**, **getUploadedFile**, **env**, **cookie**, **render**
Features
========
* The :doc:`info.xml <info>` file in **appinfo/info.xml** now supports library, command, php and database dependencies that are checked before app installation
* Various other tags for :doc:`info.xml <info>` have been added that are related to the app store
* :doc:`Routes <routes>` received the **defaults** parameter to set route variable defaults when not given
* :doc:`Routes <routes>` received the **postfix** parameter to allow multiple urls pointing at the same resource
* :doc:`Menu buttons <css>` can now be added easily for navigation entries
* **OCP\\AppFramework\\DataResponse** can now be used to wrap data and set Http error codes when using responders
* :doc:`Navigation entry undo and edit styles <css>` have been added
* **OCP\\AppFramework\\HttpResponse** now supports setting cookies
* A :doc:`container <container>` is now optional
* The :doc:`container <container>` can now automatically resolve and build classes based on type hints and variable naming conventions
* :doc:`Routes <routes>` can now be returned as an array in **appinfo/routes.php** if the **<namespace>** tag is set in **appinfo/info.xml**. The :doc:`container <container>` must either be omitted or available under **appinfo/application.php** and named **OCA\\YourApp\\YourNamespace\\AppInfo\\Application**
* **vendor_script** and **vendor_style** :doc:`template functions <templates>` have been added to load styles and scripts from your **vendor** folder
* The documentation now features an :doc:`app tutorial <tutorial>`

View File

@@ -14,7 +14,7 @@ To create a controller, simply extend the Controller class and create a method t
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use \OCP\AppFramework\Controller;
class AuthorController extends Controller {
@@ -34,9 +34,9 @@ To connect a controller and a route the controller has to be registered in the :
<?php
namespace OCA\MyApp\AppInfo;
use OCP\AppFramework\App;
use \OCP\AppFramework\App;
use OCA\MyApp\Controller\AuthorApiController;
use \OCA\MyApp\Controller\AuthorApiController;
class Application extends App {
@@ -98,7 +98,7 @@ All those parameters can easily be accessed by adding them to the controller met
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use \OCP\AppFramework\Controller;
class PageController extends Controller {
@@ -117,7 +117,7 @@ It is also possible to set default parameter values by using PHP default method
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use \OCP\AppFramework\Controller;
class PageController extends Controller {
@@ -150,7 +150,7 @@ would be passed in as the string *'false'* which is not what one would expect. T
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use \OCP\AppFramework\Controller;
class PageController extends Controller {
@@ -196,7 +196,7 @@ It is possible to pass JSON using a POST, PUT or PATCH request. To do that the *
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use \OCP\AppFramework\Controller;
class PageController extends Controller {
@@ -218,8 +218,8 @@ Headers, files, cookies and environment variables can be accessed directly from
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\IRequest;
use \OCP\AppFramework\Controller;
use \OCP\IRequest;
class PageController extends Controller {
@@ -256,8 +256,8 @@ Returning JSON is simple, just pass an array to a JSONResponse:
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\JSONResponse;
class PageController extends Controller {
@@ -275,7 +275,7 @@ Because returning JSON is such an common task, there's even a shorter way how to
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use \OCP\AppFramework\Controller;
class PageController extends Controller {
@@ -321,8 +321,8 @@ By default there is only a responder for JSON but more can be added easily:
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\DataResponse;
class PageController extends Controller {
@@ -357,9 +357,9 @@ Because returning values works fine in case of a success but not in case of fail
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\Http;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\DataResponse;
use \OCP\AppFramework\Http\Http;
class PageController extends Controller {
@@ -395,8 +395,8 @@ A :doc:`template <templates>` can be rendered by returning a TemplateResponse. A
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\TemplateResponse;
class PageController extends Controller {
@@ -417,8 +417,8 @@ A redirect can be achieved by returning a RedirectResponse:
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\RedirectResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\RedirectResponse;
class PageController extends Controller {
@@ -437,8 +437,8 @@ A file download can be triggered by returning a DownloadResponse:
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DownloadResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\DownloadResponse;
class PageController extends Controller {
@@ -462,7 +462,7 @@ Creating a custom XMLResponse class could look like this:
<?php
namespace OCA\MyApp\Http;
use OCP\AppFramework\Http\Response;
use \OCP\AppFramework\Http\Response;
class XMLResponse extends Response {
@@ -481,89 +481,6 @@ Creating a custom XMLResponse class could look like this:
}
Streamed and lazily rendered responses
--------------------------------------
.. versionadded:: 8.1
By default all responses are rendered at once and sent as a string through middleware. In certain cases this is not a desirable behavior, for instance if you want to stream a file in order to save memory. To do that use the now available **OCP\\AppFramework\\Http\\StreamResponse** class:
.. code-block:: php
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\StreamResponse;
class PageController extends Controller {
public function downloadXMLFile() {
return new StreamResponse('/some/path/to/file.xml');
}
}
If you want to use a custom, lazily rendered response simply implement the interface **OCP\\AppFramework\\Http\\ICallbackResponse** for your response:
.. code-block:: php
<?php
namespace OCA\MyApp\Http;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\ICallbackResponse;
class LazyResponse extends Response implements ICallbackResponse {
public function callback(IOutput $output) {
// custom code in here
}
}
.. note:: Because this code is rendered after several usually built in helpers, you need to take care of errors and proper HTTP caching by yourself.
OCS
---
.. versionadded:: 8.1
.. note:: This is purely for compatibility reasons. If you are planning to offer an external API, go for a :doc:`api` instead.
In order to ease migration from OCS API routes to the App Framework, an additional controller and response have been added. To migrate your API you can use the **OCP\\AppFramework\\OCSController** baseclass and return your data in the form of an array in the following way:
.. code-block:: php
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\OCSController;
class ShareController extends OCSController {
/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
* @CORS
*/
public function getShares() {
return [
'data' => [
// actual data is in here
],
// optional
'statuscode' => 100,
'status' => 'OK'
];
}
}
The format parameter works out of the box, no intervention is required.
Handling errors
---------------
@@ -576,9 +493,9 @@ Each response subclass has access to the **setStatus** method which lets you set
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http;
use \OCP\AppFramework\Http\JSONResponse;
class AuthorController extends Controller {
@@ -619,8 +536,8 @@ A controller method that turns off all checks would look like this:
<?php
namespace OCA\MyApp\Controller;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use \OCP\IRequest;
use \OCP\AppFramework\Controller;
class PageController extends Controller {
@@ -634,5 +551,3 @@ A controller method that turns off all checks would look like this:
}
}

View File

@@ -4,7 +4,33 @@ Database Access
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
The basic way to run a database query is to use the database connection provided by **OCP\\IDBConnection**.
The basic way to run a database query is to inject the **Db** service.
.. code-block:: php
<?php
namespace OCA\MyApp\AppInfo;
use \OCP\AppFramework\App;
use \OCA\MyApp\Db\AuthorDAO;
class Application extends App {
public function __construct(array $urlParams=array()){
parent::__construct('myapp', $urlParams);
$container = $this->getContainer();
/**
* Database Layer
*/
$container->registerService('AuthorDAO', function($c) {
return new AuthorDAO($c->query('ServerContainer')->getDb());
});
}
}
Inside your database layer class you can now start running queries like:
@@ -15,27 +41,27 @@ Inside your database layer class you can now start running queries like:
namespace OCA\MyApp\Db;
use OCP\IDBConnection;
use \OCP\IDb;
class AuthorDAO {
private $db;
public function __construct(IDBConnection $db) {
public function __construct(IDb $db) {
$this->db = $db;
}
public function find($id) {
$sql = 'SELECT * FROM `*PREFIX*myapp_authors` ' .
'WHERE `id` = ?';
$stmt = $this->db->prepare($sql);
$stmt->bindParam(1, $id, \PDO::PARAM_INT);
$stmt->execute();
$query = $db->prepareQuery($sql);
$query->bindParam(1, $id, \PDO::PARAM_INT);
$result = $query->execute();
$row = $stmt->fetch();
$stmt->closeCursor();
return $row;
while($row = $result->fetchRow()) {
return $row;
}
$result->closeCursor();
}
}
@@ -45,7 +71,7 @@ Mappers
=======
The aforementioned example is the most basic way write a simple database query but the more queries amass, the more code has to be written and the harder it will become to maintain it.
To generalize and simplify the problem, split code into resources and create an **Entity** and a **Mapper** class for it. The mapper class provides a way to run SQL queries and maps the result onto the related entities.
To generalize and simplify the problem, split code into resources and create an **Entity** and a **Mapper** class for it. The mapper class provides a way to run Sql queries and maps the result onto the related entities.
To create a mapper, inherit from the mapper baseclass and call the parent constructor with the following parameters:
@@ -61,12 +87,12 @@ To create a mapper, inherit from the mapper baseclass and call the parent constr
namespace OCA\MyApp\Db;
use OCP\IDBConnection;
use OCP\AppFramework\Db\Mapper;
use \OCP\IDb;
use \OCP\AppFramework\Db\Mapper;
class AuthorMapper extends Mapper {
public function __construct(IDBConnection $db) {
public function __construct(IDb $db) {
parent::__construct($db, 'myapp_authors');
}
@@ -78,7 +104,7 @@ To create a mapper, inherit from the mapper baseclass and call the parent constr
public function find($id) {
$sql = 'SELECT * FROM `*PREFIX*myapp_authors` ' .
'WHERE `id` = ?';
return $this->findEntity($sql, [$id]);
return $this->findEntity($sql, array($id));
}
@@ -91,22 +117,14 @@ To create a mapper, inherit from the mapper baseclass and call the parent constr
public function authorNameCount($name) {
$sql = 'SELECT COUNT(*) AS `count` FROM `*PREFIX*myapp_authors` ' .
'WHERE `name` = ?';
$stmt = $this->execute($sql, [$name]);
$query = $this->db->prepareQuery($sql);
$query->bindParam(1, $name, \PDO::PARAM_STR);
$result = $query->execute();
$row = $stmt->fetch();
$stmt->closeCursor();
return $row['count'];
}
public function authorNameCountNamedArguments($name) {
$sql = 'SELECT COUNT(*) AS `count` FROM `*PREFIX*myapp_authors` ' .
'WHERE `name` = :name';
$stmt = $this->execute($sql, [':name' => $name]);
$row = $stmt->fetch();
$stmt->closeCursor();
return $row['count'];
while($row = $result->fetchRow()) {
$result->closeCursor();
return $row['count'];
}
}
}
@@ -121,7 +139,33 @@ or::
$authorMapper->update($entity);
Mappers should be registered in the constructor to reuse them inside the application:
.. code-block:: php
<?php
namespace OCA\MyApp\AppInfo;
use \OCP\AppFramework\App;
use \OCA\MyApp\Db\AuthorMapper;
class Application extends App {
public function __construct(array $urlParams=array()){
parent::__construct('myapp', $urlParams);
$container = $this->getContainer();
/**
* Database Layer
*/
$container->registerService('AuthorMapper', function($c) {
return new AuthorMapper($c->query('ServerContainer')->getDb());
});
}
}
Entities
========
@@ -136,7 +180,7 @@ Entities are data objects that carry all the table's information for one row. Ev
// db/author.php
namespace OCA\MyApp\Db;
use OCP\AppFramework\Db\Entity;
use \OCP\AppFramework\Db\Entity;
class Author extends Entity {
@@ -171,7 +215,7 @@ Since all attributes should be protected, getters and setters are automatically
// db/author.php
namespace OCA\MyApp\Db;
use OCP\AppFramework\Db\Entity;
use \OCP\AppFramework\Db\Entity;
class Author extends Entity {
protected $stars;
@@ -198,7 +242,7 @@ mapping, simply override the **columnToProperty** and **propertyToColumn** metho
// db/author.php
namespace OCA\MyApp\Db;
use OCP\AppFramework\Db\Entity;
use \OCP\AppFramework\Db\Entity;
class Author extends Entity {
protected $stars;

View File

@@ -30,7 +30,6 @@ The most important labels and their meaning:
* #p1-urgent #p2-high #p3-medium #p4-low signify the priority of the bug.
* #Junior Job - these are issues which are relatively easy to solve and ideal for people who want to learn how to code in ownCloud
* Tags showing the state of the issue or PR, numbered 1-6:
* #1 - Backlog - (please don't use, we prefer using a backlog milestone)
* #2 - Triaging - (please don't use, we prefer using the triage label)
* #3 - To develop - ready to start development on this
@@ -38,7 +37,6 @@ The most important labels and their meaning:
* #5 - To Review - ready for review
* #6 - Reviewing - review in progress
* #7 - To Release - reviewed PR that awaits unfreeze of a branch to get merged
* App tags: #app:files #app:user_ldap #app:files_encryption and so on. These tags indicate the app that is impacted by the issue or which the PR is related to
* settings tags: #settings:personal #settings:apps #settings:admin and so on. These tags indicate the settings area that is impacted by the issue or which the PR is related to
* db tags: #db:mysql #db:sqlite #db:postgresql and so on. These tags indicate the database that is impacted by the issue or which the PR is related to

View File

@@ -17,12 +17,10 @@ First `set up your web server and database <http://doc.owncloud.org/server/8.0/a
Get the source
==============
There are two ways to obtain ownCloud sources:
There are two ways to obtain ownCloud sources:
* Using the `stable version <http://doc.owncloud.org/server/8.0/admin_manual/#installation>`_
.. TODO ON RELEASE: Update version number above on release
* Using the development version from `GitHub`_ which will be explained below.
To check out the source from `GitHub`_ you will need to install git (see `Setting up git <https://help.github.com/articles/set-up-git>`_ from the GitHub help)
@@ -33,14 +31,14 @@ Gather information about server setup
To get started the basic git repositories need to cloned into the web server's directory. Depending on the distribution this will either be
* **/var/www**
* **/var/www/html**
* **/srv/http**
* **/var/www/html**
* **/srv/http**
Then identify the user and group the web server is running as and the Apache user and group for the **chown** command will either be
* **http**
* **www-data**
* **www-data**
* **apache**
* **wwwrun**
@@ -54,7 +52,7 @@ Install the `development tool <https://github.com/owncloud/ocdev/blob/master/REA
After the development tool installation make the directory writable::
sudo chmod o+rw /var/www
Then install ownCloud from git::
ocdev setup base