Merge manually pull-request #2658

This commit is contained in:
Frederic Guillot 2016-09-11 22:00:09 -04:00
parent f1d6673050
commit 20c187880c
No known key found for this signature in database
GPG Key ID: 92D77191BA7FBC99
26 changed files with 1516 additions and 0 deletions

View File

@ -0,0 +1,24 @@
Análisis para tareas
===================
Cada tarea tiene una sección de análisis disponible en el menu izquierdo en la vista de tarea.
Espera y tiempo de ciclo
-------------------
![Lead and cycle time](https://kanboard.net/screenshots/documentation/task-lead-cycle-time.png)
- El tiempo de espera es el tiempo entre la creacion de la tarea y la fecha de finalización (Tarea cerrada).
- El tiempo de ciclo es el tiempo entre la fecha de inicio y la fecha de finalización.
- Si la tarea no esta cerrada el tiempo actual es usado en lugar de la fecha de finalización.
- Si la fecha de inicio no es especificada, el tiempo de ciclo no es calculado.
Nota: Puede configurar una accion automatica para definir la fecha de inicio automaticamente cuando se mueve una tarea a la columna de su eleccion.
El tiempo invertido en cada columna
---------------------------
![Time spent into each column](https://kanboard.net/screenshots/documentation/time-into-each-column.png)
- Esta gráfico muestra el total de tiempo invertido en cada columna para la tarea.
- El tiempo invertido es calculado hasta que la tarea es cerrada.

View File

@ -0,0 +1,18 @@
Modo colapsar y expandir
===========================
Las tares en el tablero pueden visualizarse en modo colapsado o en modo expandido.
El cambio entre el desplazamiento horizontal y la vista compacta se puede hacer con la combinación de teclas **"s"** o usar el menu drop-down que esta parte superior izquierda.
Modo de colapsado
--------------
![Tareas colapsadas](screenshots/board-collapsed-mode.png)
- Si la tarea es asignada a alguien, las iniciales de la persona se muestran junto al número de tareas
- Si el titulo de la tarea es demasiado largo, tu puedes poner el puntero del ratón sobre la tarea de mostrar una información sobre herramientas con el título completo
Modo expansivo
--------------
![Tasks expanded](screenshots/board-expanded-mode.png)

View File

@ -0,0 +1,25 @@
Configuración del tablero
==========================
Ir al menu **Configuraciones **, elije **Ajustes de tablero ** a la izquierda.
![Board settings](https://kanboard.net/screenshots/documentation/board-settings.png)
### Resaltado de tarea
Esta caracterista muestra una sombra alrededor de la tarea cuando una tarea se trasladó recientemente
Establecer el valor 0 para desactivar esta caracterista, 2 dias por default (172800 segundos).
Todo lo trasladó desde de 2 dias tendra una sombra alrededor de la tarea.
### Recargar el intervalo para la pizarra publica
Cuando tu compartes un tablero, la pagina se refresca cada 60 segundos automaticamente por default.
### Refrescar el intervalo para un tablero privado
Cuando su navegador está abierto un tablero, Kanboard comprueba cada 10 segundos si algo ha sido cambiado por otra persona.
Técnicamente este proceso se lleva a cabo por el Ajax.

View File

@ -0,0 +1,12 @@
Horizontal scrolling y modo compacto
=====================================
Cuando el tablero no puede caber en su pantalla , una barra de scroll horizontal
When the board cannot fit on your screen, a horizontal scroll bar aparecerá en la parte inferior.
Sin embargo, es posible cambiar a una vista de modo compacto para visualizar todas las columnas en su pantalla.
![Cambiar a modo compacto](screenshots/board-compact-mode.png)
Cambiar entre scrolling y vista compacta
El cambio entre el desplazamiento horizontal y la vista compacta se puede hacer con la combinación de teclas **"c"** o usar el menu drop-down que esta parte superior izquierda.

View File

@ -0,0 +1,12 @@
Mostrar y ocultar columnas en el tablero
==================================
Se puede ocultar o visualizar columnas muy facilmente en el tablero:
![Ocultar una columna](screenshots/hide-column.png)
Para ocultar una columna, click en la columna escoge en el menu dropdown "ocultar esta columna" :
![Mostrar una columna](screenshots/show-column.png)
Para mostar nuevamente la columna, click en el icono con el simbolo de suma "plus icon"

View File

@ -0,0 +1,67 @@
Directrices del contribuyente
======================
¿Cómo puedo ayudar?
-----------------
Kanboard no es perfecto, pero hay muchas maneras de ayudar:
- Dar opinión
- Informar de los errores
- Añadir o actualizar traducciones
- Mejorar la documentación
- Código de Escritura
- Dile a tus amigos que Kanboard es impresionante
Antes de hacer cualquier empresa grande, abrir un nuevo tema y explicar su propuesta.
Quiero dar retroalimentación
-----------------------
- Usted piensa que algo debe ser mejorado (interface de usuario, peticiones de características)
- Comprobar si aún no se propuso su idea
- Abrir un nuevo tema
- Describir su idea
- Puede también hacer un voto con +1 en las propuestas existentes
Quiero informar de un error
---------------------------
- Compruebe si el problema no se ha comunicado anteriormente
- Abrir un nuevo ticket
- Explicar lo que está roto
- Describir la forma de reproducir el error
- Describir su entorno (versión Kanboard, sistema operativo, servidor web, Versión de PHP , la versión de la base de datos, el proveedor de alojamiento)}
Deseo traducir Kanboard
----------------------------
Kanboard se traduce en muchos idiomas.
Sin embargo, las traducciones no están completas, observe la [guía de traducción para contribuir] (https://kanboard.net/documentation/translations).
Quiero mejorar la documentación
-----------------------------------
- ¿Crees que algo no está claro, existen errores gramaticales, errores tipográficos, otra cosa ?
- La documentación está escrita en Markdown y se almacena en la carpeta `docs`.
- Editar los archivos y enviar un Pull-Request
- La documentación se sincroniza con el repositorio y el sitio web oficial .
Quiero contribuir al código
--------------------------------
Los pulls son siempre bienvenidos , al ser aceptado se tiene que seguir estas directrices:
- ** Antes de hacer cualquier cambio grande o propuesta de diseño, abrir un nuevo ticket en comenzar una discusión **.
- Si desea agregar una nueva función, respetar la filosofía detrás de Kanboard. ** Nos centramos en la simplicidad **, no queremos tener un software sobrecargado .
- Lo mismo se aplica para la interface de usuario, ** ** simplicidad y eficiencia.
- Enviar un solo pull por característica o corrección de errores.
- Un pull más pequeño es más fácil y más rápido para revisar y fusionarlo.
- Asegurarse [ de hacer las pruebas unitarias (tests.markdown).
- Respetar los [estandares de codificación] (coding-standards.markdown).
- Escribir código mantenible, evitar la duplicación de código, usar las buenas practicas de PHP.
En cualquier caso, si no está seguro acerca de algo abierto crear un uevo ticket.
Dile a tus amigos que Kanboard es impresionante
---------------------------------------------
Si utiliza Kanboard, corre la voz que le rodean.
Diles que es software libre y de código abierto esto es cool.

View File

@ -0,0 +1,99 @@
Arquitectura de autenticación
=============================
Kanboard provee una flexible y conectable arquitectura de autenticación.
Por default, el usuario puede autenticarse con multiple metodos:
- Autenticación por usuario y password (Base de datos local y LDAP)
- Autenticación OAuth2
- Autenticación Reverse-Proxy
- Autenticación basada en Cookie (Recuerdame)
Además, despues de una autenticación satisfactoria un puede hacerse post de autenticación Two-Factor .
Kanboard sopoarta nativamente el standart TOTP.
Interfaces de autenticación
----------------------------
Para tener un sistema conectable, los drivers de autenticación deben implementar un conjunto de interfaces
| Interface | Rol |
|------------------------------------------|------------------------------------------------------------------|
| AuthenticationProviderInterface | Interface base para otras interfaces de autenticación |
| PreAuthenticationProviderInterface | The user is already authenticated al alcanzar la aplicación, Usualmente los servidores web definen algunas variables de entorno |
| PasswordAuthenticationProviderInterface | El metodo de autenticación que usa el username y password provienen del formulario de login |
| OAuthAuthenticationProviderInterface | Proveedores OAuth2 |
| PostAuthenticationProviderInterface | Drivers de autenticación Two-Factor ,pide el código a confirmar |
| SessionCheckProviderInterface | Los proveedores que son capaces de comprobar si la sesión de usuario es válida |
### Ejemplos de autenticación de proveedores:
- Database por default metodos a implementar `PasswordAuthenticationProviderInterface` y `SessionCheckProviderInterface`
- Reverse-Proxy metodos a implementar `PreAuthenticationProviderInterface` y `SessionCheckProviderInterface`
- Google metodos a implementar `OAuthAuthenticationProviderInterface`
- LDAP metodos a implementar `PasswordAuthenticationProviderInterface`
- RememberMe cookie metodos a implementar `PreAuthenticationProviderInterface`
- Two-Factor TOTP metodos a implementar `PostAuthenticationProviderInterface`
flujo de trabajo de autenticación ** Workflow **
------------------------------------------------
Para cada peticion HTTP:
1. Si la sesión de usuario esta abierta, ejecuta el registro de proveedores que implementa`SessionCheckProviderInterface`
2. Ejecuta todos los proveedores que implementa `PreAuthenticationProviderInterface`
3. Si el usuario final hace un submit al formulario del login, Los proveedores que implementa `PasswordAuthenticationProviderInterface` are executed
4. Si el usuario final quiere usar OAuth2, el selecciona el proveedor a ejecutar
5. Despues de una autenticación satisfactoria, el ultimo registro utilizará `PostAuthenticationProviderInterface`
6. Sincronizar la información del usuario si es necesario
Este workflow es manejado por la clase `Kanboard\Core\Security\AuthenticationManager`.
Eventos disparados:
- `AuthenticationManager::EVENT_SUCCESS`: autenticación satisfactoria
- `AuthenticationManager::EVENT_FAILURE`: autenticación fallida
Cada vez que se produce un evento de fallo , el contador de intentos fallidos se incrementa.
La cuenta de usuario se puede bloquear para el período de tiempo configurado y un captcha puede ser mostrado para evitar ataques de fuerza bruta .
Interface de usuario del proveedor
---------------------------------
Cuando la autenticación es satisfactoria, la `AuthenticationManager` pedura la información del usuario para que el driver llame al metodo `getUser()`.
Este metodo debe regresar un objeto que implementa la interface `Kanboard\Core\User\UserProviderInterface`.
Esta clase abstracta reune la información dede otro sistema.
Ejemplos :
- `DatabaseUserProvider` proporciona información para un usuario interno
- `LdapUserProvider` para un usuario LDAP
- `ReverseProxyUserProvider` para un usuario Reverse-Proxy
- `GoogleUserProvider` represtan un usuario de Google
Los métodos para la interface del proveedor de Usuario:
- `isUserCreationAllowed()`: Regresa true para permitir la creación automática de usuarios
- `getExternalIdColumn()`: Obtener Identificación del nombre de la columna externa (google_id, github_id, gitlab_id...)
- `getInternalId()`: Obtener el id interno de la base de datos
- `getExternalId()`: Obtener el id externo(Unique id)
- `getRole()`: Obtener el rol de usuario
- `getUsername()`: Obtener en nombre de usuario ** username **
- `getName()`: Obtener nombre completo del usuario
- `getEmail()`: Obtener el correo electronico del usuario
- `getExternalGroupIds()`: Obtiene los ids externos del grupo, automáticamente sincroniza la membresia del grupo y la presenta
- `getExtraAttributes()`: Obtiene los atributos extras para ser mostrados a el usuario durante la sincronización local
No es obligatorio que el metodo devuelva un valor.
Sincronización de un usuario local
----------------------------------
La información del usuario puede ser sincronizada automáticamente con la base de datos local.
- Si el metodo`getInternalId()` regresa un valor no realiza la sincronización
- Los metodos `getExternalIdColumn()` y `getExternalId()` debe regresar un valor para sincronizar el usuario
- Las propiedades que regresan un ** String ** vacios no se sincronizan

View File

@ -0,0 +1,42 @@
Plugin de autenticación
=====================
EL nuevo backend de autenticación se puede escribir con muy pocas lineas de codigo.
Registro de proveedores
-----------------------
En el metodo `initialize()` nuestro plugin, llama al metodo `register()` de la clase `AuthenticationManager`:
```php
public function initialize()
{
$this->authenticationManager->register(new ReverseProxyLdapAuth($this->container));
}
```
El objeto proveniente de el metodo `register()` debe implementar one de las interfaces de autenticación predefidas.
Esas interfaces estan definidas en los namespace `Kanboard\Core\Security`:
- `Kanboard\Core\Security\PreAuthenticationProviderInterface`
- `Kanboard\Core\Security\PostAuthenticationProviderInterface`
- `Kanboard\Core\Security\PasswordAuthenticationProviderInterface`
- `Kanboard\Core\Security\OAuthAuthenticationProviderInterface`
El único requisito es implementar las interfaces, la clase se puede escribir de la manera deseada y situado en cualquier lugar en el disco
Usuario del proveedor
----------------------
Cuando la autenticación es satisfactoria, tu driver debe regresar un objato que representa al usuario.
Este objeto debe implementasr la interface `Kanboard\Core\User\UserProviderInterface`.
Ejemplo de plugin de autenticación
----------------------------------
- [Autenticación de proveedores incluido en kanboard](https://github.com/kanboard/kanboard/tree/master/app/Auth)
- [Reverse-Proxy Autenticación con soporte LDAP](https://github.com/kanboard/plugin-reverse-proxy-ldap)
- [Two-Factor Autenticación SMS](https://github.com/kanboard/plugin-sms-2fa)

View File

@ -0,0 +1,39 @@
Arquitecuta de autorización
===========================
Kanboard [soporta multiples roles](roles.markdown) a nivel de aplicación y a nivel de proyecto.
Workflow de autorización
--------------------------
Para cada solicitud HTTP:
1. Autorizar o no el acceso a los recursos en base a la lista de acceso a las aplicaciones
2. Si el recurso es para un projecto (board, tarea...):
1. Extrae los roles de usuario para este proyecto
2. Permitir/Denegar accesos basados en el mapa de acceso del proyecto
Extendiendo mapa de accesos
---------------------------
Lista de accesos (ACL) se basa en el nombre de clase del controlador y el nombre del método
La lista de acceso está a cargo de la clase `Kanboard\Core\Security\AccessMap`.
Hay dos mapa de acceso: una para la aplicación y la otra para un proyecto.
- Acceso al mapa de aplicación : `$this->applicationAccessMap`
- Acceso al mapa del proyecto: `$this->projectAccessMap`
Ejemplos para definir una nueva política para tu plugin:
```php
// Todos los metodos de la clase MyController:
$this->projectAccessMap->add('MyController', '*', Role::PROJECT_MANAGER);
// Todos los metodos:
$this->projectAccessMap->add('MyOtherController', array('create', 'save'), Role::PROJECT_MEMBER);
```
Los roles estan defidos en la clase `Kanboard\Core\Security\Role`.
Clase de autorización (`Kanboard\Core\Security\Authorization`) comprobará el acceso de cada página.

View File

@ -0,0 +1,61 @@
Agregando acciones automáticas
===============================
Agregando una nueva acccion automática es bastante simple.
Creando una nueva accion
------------------------
Tus acciones automáticas deben heradarse de la clase `Kanboard\Action\Base`.
Varios métodos abstractos deben ser implementadas por sí mismo:
| Metodos | Descripción |
|-------------------------------------|------------------------------------------------------------------|
| `getDescription()` | Descripcion visible en la interface del usuario |
| `getCompatibleEvents()` | Obtener las listas de eventos compatibles |
| `getActionRequiredParameters()` | Obtener los parametros requeridos para la acción (definidos por el usuario)|
| `getEventRequiredParameters()` | Obtener los parametros requeridos para el evento |
| `doAction(array $data)` | Ejecutar la acción, Debe regresar true si fue satisfactorio |
| `hasRequiredCondition(array $data)` | Comprobar si los datos de eventos cumplen la condición de acción |
Tu accion automatica es identificada en kanboard utilizando el nombre de la clase absoluta con el espacio de nombre incluido
Agregando nuevos eventos
------------------------
La lista de eventos de la aplicación está disponible en la clase `Kanboard\Core\Event\EventManager::getAll()`.
Sin embargo, si tu plugin dispara nuevos eventos, tu puedes registrar estos eventos :
```php
$this->actionManager->getAction('\Kanboard\Plugin\MyPlugin\MyActionName')->addEvent('my.event', 'My event description');
```
Tu puedes extender la lista de eventos compatibles de acciones existentes para ser usada en algun metodo.
Registra la acción
----------------------
Tu tienes que llamar el metodo `register()` desde la clase `Kanboard\Core\Action\ActionManager`:
```php
<?php
namespace Kanboard\Plugin\AutomaticAction;
use Kanboard\Core\Plugin\Base;
use Kanboard\Plugin\AutomaticAction\Action\TaskRename;
class Plugin extends Base
{
public function initialize()
{
$this->actionManager->register(new TaskRename($this->container));
}
}
```
Ejemplo
-------
- [Ejemplo de acción automatica](https://github.com/kanboard/plugin-example-automatic-action)

View File

@ -0,0 +1,32 @@
Agregando un nuevo avatar del proveedor
=======================================
Registrar
------------
```php
$this->avatarManager->register(new CustomAvatarProvider());
```
Interface
---------
El proveedor debe implementar la interface `Kanboard\Core\User\Avatar\AvatarProviderInterface`:
| Metodo | Descripcion |
|-------------------------------|---------------------------------------------------------------|
| `render(array $user, $size)` | Renderizar HTML |
| `isActive(array $user)` | Regresa un boolean si el proveedor esta activo |
El argumento `$user` es un directorio que contiene estas llaves :
```php
[
'id' => 123,
'username' => 'admin',
'name' => 'Administrator',
'email' => 'me@localhost',
]
```

View File

@ -0,0 +1,15 @@
Plugin de configuración del directorio
======================================
Para instalar, actualizar y eliminar plugins dede la interface de usuario, debes tener estos requerimientos:
- El directorio del plugin debe ser de escritura por el usuario del servidor web
- La extensión Zip debe estar disponible en tu server.
- Los parametros de configuración `PLUGIN_INSTALLER` deben estar en `true`
Para desactivar esta función , cambie el valor de `PLUGIN_INSTALLER` a `false` en tu archivo de configuración.
También puede cambiar los permisos de la carpeta Plugin en el filesystem.
Sólo los administradores pueden instalar plugins desde la interfaz de usuario.
Por defecto, sólo plug-in que aparece en la página web de Kanboard están disponibles .

View File

@ -0,0 +1,27 @@
Uso de eventos
===============
Kanboard usar internamente el [ Componente EventDispatcher de Symfony ](https://symfony.com/doc/2.3/components/event_dispatcher/index.html) para manegar internamente los eventos.
Eventos escucha ** Listening **
-------------------------------
```php
$this->on('app.bootstrap', function($container) {
// tu codigo
});
```
- El primer argumento es el nombre del evento (string)
- El segundo argumento es una funcion PHP callable (finalización o metodos de la clase)
Agregando un nuevo evento
-------------------------
Para agregar un nuevo, tienes que llamar al metodo `register()` de la clase `Kanboard\Core\Event\EventManager`:
```php
$this->eventManager->register('my.event.name', 'Mi descripcion del nuevo evento');
```
Estos eventos pueden ser utilizados por otros componentes de Kanboard como acciones automáticas .

View File

@ -0,0 +1,79 @@
Vinculación externa de proveedores
==================================
Esta funcionalidad le permite vincular una tarea a los elementos adicionales almacenados en otro sistema.
Por ejemplo, tu puedes vincular una tarea a:
For example, you can link a task to:
- Una pagina web tradicional
- Datos adjuntos (Documentos PDF almacenados en la web, archivos ...)
- Cualquier sitema de tickets (bug tracker, soporte personalizado de tickets...)
Cada item tiene un tipo, u na URL, un tipo dedependencia y un titulo.
Por default,Kanboard incluye dos tipos de proveedores
- Vinculación Web : Copiar y pegar un enlace y Kanboard se ha podido ir a la página de título de forma automática.
- Datos adjuntos: Enlace a todo lo que no es una página web
Flujo de trabajo ** Workflow **
--------------------------------
1. El usuario final copia y pega el URL al submit del formulario.
2.- Si el tipo de link es "auto", Kanboard crea un bucle a través de todos los proveedores registrados hasta que hay una coincidencia
3. Entonces , el proveedor de enlace devuelve un objeto que implementa la interfaz de `ExternalLinkInterface`
4. El formulario se muestra al usuario con todos los datos precargados antes de guardar el enlace
Interfaces
----------
Para implementar un nuevo vinculo al proveedor desde un plugin, es necesario crear 2 clases que implementarlas en las interfaces:
- `Kanboard\Core\ExternalLink\ExternalLinkProviderInterface`
- `Kanboard\Core\ExternalLink\ExternalLinkInterface`
### ExternalLinkProviderInterface
| Method | Usage |
|----------------------------|---------------------------------------------------------------------------------|
| `getName()` | Obtener el nombre del proveedor(label) |
| `getType()` | Obtener el tipo de link (se guardarán en la base de datos) |
| `getDependencies()` | Obtener un diccionario de los tipos de dependencia soportados por el proveedor |
| `setUserTextInput($input)` | Texto introducido por el usuario |
| `match()` | Regresa true si el proveedor puede analizar correctamente la entrada del usuario|
| `getLink()` | Obtener el enlace que se encuentra con las propiedades |
### ExternalLinkInterface
| Method | Usage |
|-------------------|-----------------------------|
| `getTitle()` | Obtiene un titulo de link |
| `getUrl()` | Obtiene una link de URL |
| `setUrl($url)` | URL del enlace |
El registro de un nuevo proveedor de enlace
------------------------------------------
En tu `Plugin.php`, solo puedes llamar al metodo `register()` desde el objeto `ExternalLinkManager`:
```php
<?php
namespace Kanboard\Plugin\MyExternalLink;
use Kanboard\Core\Plugin\Base;
class Plugin extends Base
{
public function initialize()
{
$this->externalLinkManager->register(new MyLinkProvider());
}
}
```
Ejemplos
--------
- Kanboard incluye proveedores por default "WebLink" y "Attachment"

View File

@ -0,0 +1,54 @@
Personalizar grupos de proveedores
==================================
Kanboard es capaz de cargar grupos de un sistema externo.
Esta caracteristica es principalmente usada para permisos de proyectos.
Los **Projects Managers** pueden permitir el acceso a un proyecto para un grupo
El usuario final **end-user** utilizara una caja de autocomplementar y busquedas para un grupo
Cada vez que se ejecuta una consulta de grupo , todos los proveedores de grupo registrados se ejecutan .
Flujo de trabajo del Grupo de Proveedores **Workflow**
-----------------------------------------------------
1. El usuario final **end-user** comienza a escribir el nombre del grupo y el campo se autocompleta
2. EL `GroupManager` la clase ejecuta la consulta para todos los proveedores de grupo registrados
3. Los resultados son fusionados y regresados a la interface de usuario
4. Antes de seleccionar un grupo, a información del grupo se sincronizan con la base de datos local si es necesario
Interface del grupo de proveedores
----------------------------------
interface a implementar: `Kanboard\Core\Group\GroupProviderInterface`.
Las clases que implementa esta interface abstracta del grupo de información, solo hay 3 metodos:
- `getInternalId()`: Obtiene el id interno de la base de datos, de otra manera regresa 0
- `getExternalId()`: Obtiene un id unico externo
- `getName()`: Obtiene el nombre de grupo
Kanboard utilizará el ID externo para sincronizar con la base de datos local.
Interface Backend del grupo de proveedores
------------------------------------------
Interface a implementar: `Kanboard\Core\Group\GroupBackendProviderInterface`.
Esta interface requiere solo un metodo: `find($input)`.
El argumento `$input` es el texto introducido desde la interfaz de usuario.
Este metodo debe regresar una lista de `GroupProviderInterface`, es es el resultado de la busqueda.
Backend de registro desde Plugins
---------------------------------
En el metodo `initialize()` de su plugins registrado se puede personalizar el backend :
```php
$groupManager->register(new MyCustomLdapBackendGroupProvider($this->container));
```
Ejemplos
--------
- [Kanboard incluye el grupo de provedores (LDAP y base de datos)](https://github.com/kanboard/kanboard/tree/master/app/Group)

View File

@ -0,0 +1,39 @@
Registrar nuevos helpers
=======================
Estrucura del helper:
```php
<?php
namespace Kanboard\Plugin\MyPlugin\Helper\MyHelper;
use Kanboard\Core\Base;
class MyHelper extends Base
{
public function doSomething()
{
return 'foobar';
}
}
```
Registrar tu helper en la clase:
```php
$this->helper->register('myHelper', '\Kanboard\Plugin\MyPlugin\Helper\MyHelper');
```
Usar tu helper desde una plantilla **Template**:
```php
<p>
<?= $this->myHelper->doSomething() ?>
</p>
```
Usar tu helper dese otra clase:
```php
$this->helper->myHelper->doSomething();
```

View File

@ -0,0 +1,249 @@
Plugin Hooks
============
Hooks de aplicación
-----------------
Los hooks pueden extender , reemplazar, filtar datos o cambiar los comportamientos por default, cad hook es identificado con unico nombre, ejemplo : `controller:calendar:user:events`
### Escuchar en eventos hook
En tu metodo `initialize()` tu necesitas llamar al metodo `on()` de la clase `Kanboard\Core\Plugin\Hook`:
```php
$this->hook->on('hook_name', $callable);
```
El primer argumento es el nombre del hook y el segundo es un callable PHP
### Hooks ejecutado sólo una vez
Algunos hooks solo tienen un listener:
#### model:subtask-time-tracking:calculate:time-spent
- Anular el cálculo del tiempo anterior cuando se detiene el temporizador de la subtarea
- Argumentos :
- `$user_id` (integer)
- `$start` (DateTime)
- `$end` (DateTime)
### Fusionar hooks
"Fusionar hooks" actuar de la misma manera que la función de `array_merge`. el hook callback solo regresa un array. Este array se fusionará con la que viene por defecto.
Ejemplo para agregar eventos en el calendario del usuario:
```php
class Plugin extends Base
{
public function initialize()
{
$container = $this->container;
$this->hook->on('controller:calendar:user:events', function($user_id, $start, $end) use ($container) {
$model = new SubtaskForecast($container);
return $model->getCalendarEvents($user_id, $end); // Return new events
});
}
}
```
Ejemplo para sobrescribir los valores por default de las tareas:
```php
class Plugin extends Base
{
public function initialize()
{
$this->hook->on('controller:task:form:default', function (array $default_values) {
return empty($default_values['score']) ? array('score' => 4) : array();
});
}
}
```
Lista de fusión de hooks:
#### controller:task:form:default
- sobrescribir los valores por default de las tareas
- Argumentos:
- `$default_values`: actual default values (array)
#### controller:calendar:project:events
- Agregar mas eventos a el calendario del projecto
- Argumentos:
- `$project_id` (integer)
- `$start` Calendar start date (string, ISO-8601 format)
- `$end` Calendar` end date (string, ISO-8601 format)
#### controller:calendar:user:events
- Agregar mas eventos a el calendario de usuario
- Argumentos:
- `$user_id` (integer)
- `$start` Calendar start date (string, ISO-8601 format)
- `$end` Calendar end date (string, ISO-8601 format)
Asset Hooks
-----------
Asset hooks pueden ser usados para agregar nuevas stylesheet facilmente o un nuevo archivo JavaScript en el layout. tu puedes usar estas caracteristicas para crear un tema y sobreescribir todo los estilos por dafault del kanboard.
Ejemplo para agregar un stylesheet **hoja de estilo**
```php
<?php
namespace Kanboard\Plugin\Css;
use Kanboard\Core\Plugin\Base;
class Plugin extends Base
{
public function initialize()
{
$this->hook->on('template:layout:css', array('template' => 'plugins/Css/skin.css'));
}
}
```
Lista de asset Hooks:
- `template:layout:css`
- `template:layout:js`
Referencia de hooks
---------------
La reference hooks son pasados a una variable por referencia.
Ejemplo:
```php
$this->hook->on('formatter:board:query', function (\PicoDb\Table &query) {
$query->eq('color_id', 'red');
});
```
El código anterior mostrará sólo las tareas en rojo en el tablero.
Lista de referencias de hooks:
| Hook | Description |
|--------------------------------------------|---------------------------------------------------------------|
| `formatter:board:query` | Alterar consulta a la base antes de tablero de renderizado |
| `pagination:dashboard:task:query` | Alterar consulta de base de datos para las tareas de la paginación en el dashboard |
| `pagination:dashboard:subtask:query` | Alterar consulta a la base de la paginación en el subtareas del dashboard |
| `model:task:creation:prepare` | Alterar los valores del formulario antes de guardar una tarea |
| `model:task:modification:prepare` | Alterar los valores del formulario antes de editar una tarea
Template Hooks
--------------
Template hooks permitirá añadir nuevos contenidos en las plantillas existentes.
Ejemplo para agregar nuevos contenidos en el sidebar del dashboard:
```php
$this->template->hook->attach('template:dashboard:sidebar', 'myplugin:dashboard/sidebar');
```
Ejemplo para adjuntar un template con variables locales:
```php
$this->template->hook->attach('template:dashboard:sidebar', 'myplugin:dashboard/sidebar', array(
'variable' => 'foobar',
));
```
Ejemplo para adjuntar un template con un callable:
```php
$this->template->hook->attach('template:dashboard:sidebar', 'myplugin:dashboard/sidebar', function($hook_param1, $hook_param2) {
return array('new_template_variable' => 'foobar'); // Inyectar una nueva variable en la plantilla Plugin
});
```
Este llamada es usualmente definida en el metodo `initialize()`
El primer argumento es el nombre del hook y el segundo argumento es el nombre del template.
Los nombres de plantillas con el prefijo del nombre del plugin y los dos puntos indican la ubicación de la plantilla.
Ejemplo con `myplugin:dashboard/sidebar`:
- `myplugin` Es el nombre de tu plugin (minusculas)
- `dashboard/sidebar` es el nombre del template
- En el filesystem, El plugin esta localizado aqui: `plugins\Myplugin\Template\dashboard\sidebar.php`
- Templates estan escritos en puro PHP (no se olvide de escapar los datos)
Los nombres de plantillas sin prefijo son plantillas básicas.
Lista de templates hooks:
| Hook | Descripción |
|--------------------------------------------|----------------------------------------------------|
| `template:analytic:sidebar` | Sidebar en paginas analiticas |
| `template:app:filters-helper:before` | Filtro helper dropdown (top) |
| `template:app:filters-helper:after` | Filtro helper dropdown (bottom) |
| `template:auth:login-form:before` | Pagina de login (top) |
| `template:auth:login-form:after` | Pagina de login (bottom) |
| `template:board:private:task:before-title` | Tarea en un tablero privado : despues del titulo |
| `template:board:private:task:after-title` | Tarea en un tablero privado : antes del titulo |
| `template:board:public:task:before-title` | Tarea en un tablero publico : despues del titulo |
| `template:board:public:task:after-title` | Tarea en un tablero publico : antes del titulo |
| `template:board:task:footer` | Tarea en el tablero : footer |
| `template:board:task:icons` | Tarea en el tablero: tooltip icon |
| `template:board:column:dropdown` | Menu Dropdown en las columnas del tablero |
| `template:config:sidebar` | Sidebar pagina de configuración |
| `template:config:application ` | Aplicación de configuración del formulario |
| `template:config:email` | Email settings page |
| `template:config:integrations` | Integration page in global settings |
| `template:dashboard:sidebar` | Sidebar en la pagina del dashboard |
| `template:dashboard:show` | Pagina principal del dashboard |
| `template:export:sidebar` | Sidebar para exportar paginas |
| `template:import:sidebar` | Sidebar para importar paginas |
| `template:header:dropdown` | Dropdown menu Pagina header (icono avatar de usuario) |
| `template:header:creation-dropdown` | Dropdown menu Pagina header (plus icon) |
| `template:layout:head` | Layout de la pagina `<head/>` tag |
| `template:layout:top` | Layout de la pagina top header |
| `template:layout:bottom` | Layout de la pagina footer |
| `template:project:dropdown` | "Actions" menu a la izquierda vista para diferentes proyectos |
| `template:project:header:before` | Filtros de Proyectos (antes) |
| `template:project:header:after` | Filtros de Proyectos (despues) |
| `template:project:integrations` | Pagina de integracion de configuración de proyectos|
| `template:project:sidebar` | Sidebar configuración de proyectos |
| `template:project-user:sidebar` | Sidebar en la página de la información de usuario del proyecto |
| `template:task:layout:top` | Task layout top (antes page header) |
| `template:task:details:top` | Resumen de tarea top |
| `template:task:details:bottom` | Resumen de tarea bottom |
| `template:task:details:first-column` | Resumen de tarea columna |
| `template:task:details:second-column` | Resumen de tarea dos columnas |
| `template:task:details:third-column` | Resumen de tarea tres columnas |
| `template:task:details:fourth-column` | Resumen de tarea cuatro columnas |
| `template:task:dropdown` | Task dropdown menu en listado de paginas |
| `template:task:sidebar:actions` | Sidebar on task page (sección de acciones) |
| `template:task:sidebar:information` | Sidebar on task page (sección de información) |
| `template:task:form:first-column` | 1st columna en forma de tarea |
| `template:task:form:second-column` | 2nd columna en forma de tarea |
| `template:task:form:third-column` | 3nd columna en forma de tarea |
| `template:task:show:top ` | Mostrar página de tareas : top |
| `template:task:show:bottom` | Mostrar página de tareas : bottom |
| `template:task:show:before-description` | Mostrar página de tareas : despues de la descripción |
| `template:task:show:before-tasklinks` | Mostrar página de tareas : despues tasklinks |
| `template:task:show:before-subtasks` | Mostrar página de tareas : despues subtareas |
| `template:task:show:before-timetracking` | Mostrar página de tareas : despues timetracking |
| `template:task:show:before-attachments` | Mostrar página de tareas : despues archivos adjuntos |
| `template:task:show:before-comments` | Mostrar página de tareas : despues comentarios |
| `template:user:authentication:form` | "Editar autenticación" formulario de perfil de usuario |
| `template:user:create-remote:form` | "Crear un usuario remoto" formulario |
| `template:user:external` | "Autenticación externa" la página de perfil de usuario |
| `template:user:integrations` | Integración en el perfil de usuario |
| `template:user:sidebar:actions` | Sidebar en el perfil de usuario (sección de acciones) |
| `template:user:sidebar:information` | Sidebar en el perfil de usuario (sección de información) |
Otro de los ganchos plantilla se pueden añadir en caso necesario , sólo hay que preguntar en el seguimiento de incidencias ** issue tracking **.

View File

@ -0,0 +1,99 @@
Libreria LDAP
============
Para facilirar la integracion LDAP. kanboard tiene su propia libreria LDAP
Esta libreria puede ejecutar operaciones comunes.
Cliente
-------
Clase: `Kanboard\Core\Ldap\Client`
Para conectar a tu servidor LDAP facilmente, usa este metodo:
```php
use Kanboard\Core\Ldap\Client as LdapClient;
use Kanboard\Core\Ldap\ClientException as LdapException;
try {
$client = LdapClient::connect();
// Get native LDAP resource
$resource = $client->getConnection();
// ...
} catch (LdapException $e) {
// ...
}
```
Consultas LDAP
--------------
Classes:
- `Kanboard\Core\Ldap\Query`
- `Kanboard\Core\Ldap\Entries`
- `Kanboard\Core\Ldap\Entry`
Ejemplo para una consulta al directorio LDAP:
```php
$query = new Query($client)
$query->execute('ou=People,dc=kanboard,dc=local', 'uid=my_user', array('cn', 'mail'));
if ($query->hasResult()) {
$entries = $query->getEntries(); // Return an instance of Entries
}
```
Leer una entrada:
```php
$firstEntry = $query->getEntries()->getFirstEntry();
$email = $firstEntry->getFirstValue('mail');
$name = $firstEntry->getFirstValue('cn', 'Default Name');
```
Leer multiples entradas:
```php
foreach ($query->getEntries()->getAll() as $entry) {
$emails = $entry->getAll('mail'); // Fetch all emails
$dn = $entry->getDn(); // Get LDAP DN of this user
// Check if a value is present for an attribute
if ($entry->hasValue('mail', 'user2@localhost')) {
// ...
}
}
```
Usuario Helper
--------------
Clase: `Kanboard\Core\Ldap\User`
Obtener usuario en una sola linea
```php
// Return an instance of LdapUserProvider
$user = User::getUser($client, 'my_username');
```
Grupo Helper
------------
Clase: `Kanboard\Core\Ldap\Group`
Obtener grupos en una linea:
```php
// Define LDAP filter
$filter = '(&(objectClass=group)(sAMAccountName=My group*))';
// Return a list of LdapGroupProvider
$groups = Group::getGroups($client, $filter);
```

View File

@ -0,0 +1,49 @@
Plugin: Agregar trasporte de email
==================================
Por default Kanboard soporta 3 estadares de trasporte de email:
- Mail (PHP mail function)
- Smtp
- Sendmail command
Con la API del plugin tu puedes agregar un driver para cualquier proveedor de email.
Por ejemplo, nuestro plugin puede agregar un trasporte de email para un proveedor que usa un API HTTP.
Implementación
--------------
Nuestro plugin dede implementgar la interface `Kanboard\Core\Mail\ClientInterface` y extiende desde `Kanboard\Core\Base`.
El único método que necesita para implementar es `sendEmail()`:
```php
interface ClientInterface
{
/**
* Send a HTML email
*
* @access public
* @param string $email
* @param string $name
* @param string $subject
* @param string $html
* @param string $author
*/
public function sendEmail($email, $name, $subject, $html, $author);
}
```
Para registrar el nuevo trasporte de email, usa el metodo `setTransport($transport, $class)` desde la clase `Kanboard\Core\Mail\Client`:
```php
$this->emailClient->setTransport('myprovider', '\Kanboard\Plugin\MyProvider\MyEmailHandler');
```
EL segundo argumento contiene el absoluto namespace de tu clase especifica
Ejemplos de plugins para trasporte de email
----------------------------------
- [Sendgrid](https://github.com/kanboard/plugin-sendgrid)
- [Mailgun](https://github.com/kanboard/plugin-mailgun)
- [Postmark](https://github.com/kanboard/plugin-postmark)

View File

@ -0,0 +1,42 @@
Metadatos
=========
Tu piedes adjutnar metadatos para cada projecto,tarea , usuaio o para toda la aplicación
Los metadatos son campos personalisados, es una key/value de una tabla.
Por ejemplo nuestro plugin puede almacenar información externa para una tarea o nuevas configuraciones para un proyecto.
Básicamente le permiten ampliar los campos predeterminados sin tener que crear nuevas tablas .
Adjuntar y eliminar metadatos para tareas
--------------------------------------------
```php
// Return a dictionary of metadata (keys/values) for the $task_id
$this->taskMetadataModel->getAll($task_id);
// Get a value only for a task
$this->taskMetadataModel->get($task_id, 'my_plugin_variable', 'default_value');
// Return true if the metadata my_plugin_variable exists
$this->taskMetadataModel->exists($task_id, 'my_plugin_variable');
// Create or update metadata for the task
$this->taskMetadataModel->save($task_id, ['my_plugin_variable' => 'something']);
// Remove a metadata from a project
$this->projectMetadataModel->remove($project_id, my_plugin_variable);
```
Tipos de metadatos
------------------
- TaskMetadata: `$this->taskMetadataModel`
- ProjectMetadata: `$this->projectMetadataModel`
- UserMetadata: `$this->userMetadataModel`
- Settings/Config: `$this->configModel`
Notas
-----
- Siempre prefijo del nombre de metadatos con el nombre del plugin

View File

@ -0,0 +1,59 @@
Agregar notificaciones con los tipos de plugin
==============================================
Puede enviar notificaciones a casi cualquier sistema mediante la adición de un nuevo tipo .
There are two kinds of notifications: project and user.
- Project: Notificaciones configuradas a nivel de proyecto
- Usuario: Notificaciones enviadas individualmente y configurada a cada perfil de usuario.
Registra un nuevo tipo de notificación
--------------------------------------
En tu archivo de registro del plugin llama el metodo `setType()`:
```php
$this->userNotificationTypeModel->setType('irc', t('IRC'), '\Kanboard\Plugin\IRC\Notification\IrcHandler');
$this->projectNotificationTypeModel->setType('irc', t('IRC'), '\Kanboard\Plugin\IRC\Notification\IrcHandler');
```
Su controlador puede ser registrado por el usuario o la notificación del proyecto. No necesariamente tienen que soportarlo .
Cuando tu handler es registrdo, el usuario final **end-user** puede elegir recibir el nuevo tipo de notificación o no
Notificación de Handler
-----------------------
Su controlador de notificación debe implementar la interfaz `Kanboard\Core\Notification\NotificationInterface`:
```php
interface NotificationInterface
{
/**
* Envia notificación a un usuario
*
* @access public
* @param array $user
* @param string $event_name
* @param array $event_data
*/
public function notifyUser(array $user, $event_name, array $event_data);
/**
* Envia notificacion a un projecto
*
* @access public
* @param array $project
* @param string $event_name
* @param array $event_data
*/
public function notifyProject(array $project, $event_name, array $event_data);
}
```
Ejemplo de notificacion de plugins
---------------------------------
- [Slack](https://github.com/kanboard/plugin-slack)
- [Hipchat](https://github.com/kanboard/plugin-hipchat)
- [Jabber](https://github.com/kanboard/plugin-jabber)

View File

@ -0,0 +1,42 @@
Plugin Reescritura
================
Reesritura HTTP Contenido Política de Seguridad
-----------------------------------------------
Si desea reemplazar el encabezado HTTP predeterminado de la directiva de seguridad del contenido, puede utilizar el método`setContentSecurityPolicy()`:
```php
<?php
namespace Kanboard\Plugin\Csp;
use Kanboard\Core\Plugin\Base;
class Plugin extends Base
{
public function initialize()
{
$this->setContentSecurityPolicy(array('script-src' => 'something'));
}
}
```
Plantillas de reescrituras
--------------------------
Las plantillas definidas en el núcleo se pueden anular . Por ejemplo , se puede redefinir el diseño predeterminado o cambiar notificaciones por correo electrónico.
Ejemolo de plantilla de reescritura:
```php
$this->template->setTemplateOverride('header', 'theme:layout/header');
```
El primer argumento es el nombre de la plantilla original y el segundo argumento de la plantilla para usar como reemplazo.
Puede seguir utilizando la plantilla original utilizando el prefijo "kanboard:" :
```php
<?= $this->render('kanboard:header') ?>
```

View File

@ -0,0 +1,160 @@
Registracion de Plugin
======================
Estructura del directorio
--------------------------
Los Plugins estan almacenados en el subdirectorio `plugins. Un ejemplo de estructura del directorio de un plugin:
```bash
plugins
└── Budget <= Plugin name
├── Asset <= Javascript/CSS files
├── Controller
├── LICENSE <= Plugin license
├── Locale
│ ├── fr_FR
│   ├── it_IT
│   ├── ja_JP
│   └── zh_CN
├── Model
├── Plugin.php <= Plugin registration file
├── README.md
├── Schema <= Database migrations
├── Template
└── Test <= Unit tests
```
Solamente el archivo de registración `Plugin.php` es requerido. Las otras carpetas son opcionales.
La primera letra del nombre del plugin debe ser capitalizada.
Archivo de registración del plugin
----------------------------------
Kanboard Kanboard escaneará el directorio `plugins` y cargara automaticamente todo en este directorio. el archivo `Plugin.php` se utiliza para cargar y registrar el plugin.
Ejemplo del archivo `Plugin.php` (`plugins/Foobar/Plugin.php`):
```php
<?php
namespace Kanboard\Plugin\Foobar;
use Kanboard\Core\Plugin\Base;
class Plugin extends Base
{
public function initialize()
{
$this->template->hook->attach('template:layout:head', 'theme:layout/head');
}
}
```
Este archivo debera contener una clase `Plugin` se define en el namespace `Kanboard\Plugin\Yourplugin` y extiende `Kanboard\Core\Plugin\Base`.
El único método requerido es `initialize()`. Este método se llama para cada petición cuando el plugin es cargado.
Metodos del plugin
--------------
Los métodos disponibles son `Kanboard\Core\Plugin\Base`:
- `initialize()`: ejecuta cuando el plugin es cargafo
- `getClasses()`: Regresa todas las clases que se deben almacenar en el contenedor de inyección de dependencias
- `on($event, $callback)`: Escucha eventos internos.
- `getPluginName()`: devuelve el nombre del plugin.
- `getPluginAuthor()`: Devuelve el autor del plugin.
- `getPluginVersion()`: Devuelve la versíon del plugin.
- `getPluginDescription()`: Devuelve la descripcion del plugin.
- `getPluginHomepage()`: Devuelve la pagina inicial del plugin (link)
- `setContentSecurityPolicy(array $rules)`: Reescribe las reglas por default del HTTP CSP.
- `onStartup()`: Si está presente este método, se ejecuta automáticamente cuando el evento "app.bootstrap" se dispara.
Su registro de plugin tambien puede heradar de la clase Kanboard\Core\Base, de esta manera se puede acceder a todas las clases y los métodos de Kanboard facilmente.
En este ejemplo se obtendrá el usuario #123:
```php
$this->user->getById(123);
```
Plugin de traducción
-------------------
Este plugin se puede traducir en la misma forma que el resto de la aplicación . Debe cargar las traducciones a sí mismo cuando se crea la sesión :
```php
public function onStartup()
{
Translator::load($this->languageModel->getCurrentLanguage(), __DIR__.'/Locale');
}
```
Las traducciones deben ser almacenadas en el archivo `plugins/Myplugin/Locale/xx_XX/translations.php` (remplazar xx_XX por el codigo del lenguaje fr_FR, en_US...).
Las traducciones estan almacenadas en un diccionario, Si desea sobreescribir una cadena existente, sólo tiene que utilizar la misma clave en el archivo de traducción.
Inyección de dependencias de contenedores
------------------------------
Kanboard utiliza la Pimple , un simple inyección de contenedores de dependencia PHP . Sin embargo , Kanboard puede registrar cualquier clase en el contenedor fácilmente.
Estas clases están disponibles en todas partes en la aplicación y se crea una única instancia .
Aquí un ejemplo para registrar sus propios modelos en el contenedor:
```php
public function getClasses()
{
return array(
'Plugin\Budget\Model' => array(
'HourlyRateModel',
'BudgetModel',
)
);
}
```
Ahora bien, si se utiliza una clase que se extiende desde `Core\Base`, tu puedes acceder directamente cualquier instancia de la clase:
```php
$this->hourlyRateModel->remove(123);
$this->budgetModel->getDailyBudgetBreakdown(456);
// It's the same thing as using the container:
$this->container['hourlyRateModel']->getAll();
```
Llaves de los contenedores son únicos a través de la aplicación . Si reemplaza una clase existente , que va a cambiar el comportamiento por defecto .
Agregar un metodo nuevo en la API
---------------------------------
Kanboard usa la libreria [JSON-RPC](https://github.com/fguillot/JsonRPC) para manejar las llamadas de la api.
Para agregar un nuevo metodo tu puedes que puede hacer algo para llamar a tu plugin:
```php
$this->api->getProcedureHandler()->withCallback('my_method', function() {
return 'foobar';
});
```
`$this->container['api']` or `$this->api` expose an instance of the object `JsonRPC\Server`.
Leer la documentacion de la libreria para mas información.
Agregar una nueva consola de comandos
--------------------------------------
Kanboard usa la libreria [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html) para manejar las lineas de comandos.
Kanboard genera una instancia del objeto `Symfony\Component\Console\Application` via `$this->cli`.
Tu puedes agregar nuevos comandos desde tu plugin:
```php
$this->cli->add(new MyCommand());
```
Lea la documentación de la biblioteca para obtener más información.

View File

@ -0,0 +1,85 @@
Personalizar Rutas
==================
Cuando está habilitada la reescritura de URL, tu puedes definir rutas personalizadas desde tus plugins.
Definir nuevas rutas
--------------------
Las rutas son manejadas por la clase `Kanboard\Core\Http\Route`.
Las nuevas rutas se pueden agregar mediante el uso del método `addRoute($path, $controller, $action, $plugin)`, here an example:
```php
$this->route->addRoute('/my/custom/route', 'myController', 'myAction', 'myplugin');
```
Cuando el usuario final **end-user** van a la URL `/my/custom/route`, el metodo `Kanboard\Plugin\Myplugin\Controller\MyController::myAction()` será ejecutado.
El primer caracter del contraldor y el nombre del plugin serán convertidos en mayusculas con la funcion `ucfirst()`.
Tu puedes ademas definir rutas con variables:
```php
$this->route->addRoute('/my/route/:my_variable', 'myController', 'myAction', 'myplugin');
```
El prefijo colon `:`, define una variable.
Por ejemplo `:my_variable` declare el nombre de la nueva variable `my_variable`.
Para extraer los valores de la variable puedes usar el metodo `getStringParam()` or `getIntegerParam()` desde la clase `Kanboard\Core\Http\Request`:
Si tenemos la URL `/my/route/foobar`, el valor de `my_variable` es `foobar`:
```php
$this->request->getStringParam('my_variable'); // Return foobar
```
Generate links based on the routing table
-----------------------------------------
Desde las plantillas , se tiene que usar el helper `Kanboard\Helper\Url`.
### Generar un link HTML
```php
<?= $this->url->link('My link', 'mycontroller', 'myaction', array('plugin' => 'myplugin')) ?>
```
Generara este HTML:
```html
<a href="/my/custom/route">My link</a>
```
### Generara solamente el atributo `href`:
```php
<?= $this->url->href('My link', 'mycontroller', 'myaction', array('plugin' => 'myplugin')) ?>
```
HTML salida:
```html
/my/custom/route
```
Salida HTML cuando la reescritura del URL no esta habilitada:
```html
?controller=mycontroller&amp;action=myaction&amp;plugin=myplugin
```
### Generar enlace de redirección:
Desde un controlador, si tu necesitas para From a controller, si tu necesitas realizar una redirección:
```php
$this->url->to('mycontroller', 'myaction', array('plugin' => 'myplugin'));
```
Generar:
```
?controller=mycontroller&action=myaction&plugin=myplugin
```

View File

@ -0,0 +1,40 @@
Plugin Migración de esquemas
============================
Kanboard realiza migraciones de base de datos automaticamente para ti.
Las migraciones deben ser almacenadas en una carpeta **Schema** y el nombre de archivo debe ser el mismo que el controlador de base de datos:
```bash
Schema
├── Mysql.php
├── Postgres.php
└── Sqlite.php
```
Cada archivo contiene todas las migraciones, aqui un ejemple para Sqlite:
```php
<?php
namespace Kanboard\Plugin\Something\Schema;
const VERSION = 1;
function version_1($pdo)
{
$pdo->exec('CREATE TABLE IF NOT EXISTS something (
"id" INTEGER PRIMARY KEY,
"project_id" INTEGER NOT NULL,
"something" TEXT,
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE
)');
}
```
- La constante `VERSION` es la ultima versión de tu esquema
- Cada funcion es una migración `version_1()`, `version_2()`, etc.
- Una instancia `PDO` es pasado como un primer argumneto
- Todo se ejecuta dentro de una transacción , si algo no funciona se realiza una operación de rollback y se muestra el error al usuario
Kanboard siempre compara la version definida en tu esquema y la version almacenada en la base de datos. Si la versiones son diferentes, kanboard siempre ejecuta cada migración una por una hasta alcanzar la ultima version.

View File

@ -0,0 +1,46 @@
Desarrollo de Plugin
====================
Nota : el plugin API es **considerado alpha** en estos momentos.
Los plugins son útiles para extender las funcionalidades básicas de Kanboard , la adición de características , la creación de temas o cambiar el comportamiento por defecto .
Los creadores de plugins deben especificar explícitamente las versiones compatibles de Kanboard . El código interno de Kanboard puede cambiar con el tiempo y su extensión debe ser probado con nuevas versiones . Compruebe siempre el [ChangeLog](https://github.com/kanboard/kanboard/blob/master/ChangeLog) para realizar los cambios.
- [Crear tu plugin](plugin-registration.markdown)
- [Usar plugins hooks](plugin-hooks.markdown)
- [Eventos](plugin-events.markdown)
- [Rescribir compartamientos por default en la aplicación](plugin-overrides.markdown)
- [Agregar plugins para migrar esquemas](plugin-schema-migrations.markdown)
- [Personalizar rutas](plugin-routes.markdown)
- [Agregar helpers](plugin-helpers.markdown)
- [Agregar trasportes de email ](plugin-mail-transports.markdown)
- [Agregar tipos de notificaciones](plugin-notifications.markdown)
- [Agregar acciones automaticas](plugin-automatic-actions.markdown)
- [Adjuntar metados para usuarios,tareas y proyectos](plugin-metadata.markdown)
- [Arquitectura de autenticación](plugin-authentication-architecture.markdown)
- [Registración de plugins de autenticación](plugin-authentication.markdown)
- [Arquitectura de autorización](plugin-authorization-architecture.markdown)
- [Personlizar grupos de proveedores](plugin-group-provider.markdown)
- [Links externos para proveedores](plugin-external-link.markdown)
- [Agregar avatar a proveedores](plugin-avatar-provider.markdown)
- [Cliente LDAP](plugin-ldap-client.markdown)
Ejemplos de plugins
-------------------
- [SMS Two-Factor Authentication](https://github.com/kanboard/plugin-sms-2fa)
- [Reverse-Proxy Authentication with LDAP support](https://github.com/kanboard/plugin-reverse-proxy-ldap)
- [Slack](https://github.com/kanboard/plugin-slack)
- [Hipchat](https://github.com/kanboard/plugin-hipchat)
- [Jabber](https://github.com/kanboard/plugin-jabber)
- [Sendgrid](https://github.com/kanboard/plugin-sendgrid)
- [Mailgun](https://github.com/kanboard/plugin-mailgun)
- [Postmark](https://github.com/kanboard/plugin-postmark)
- [Amazon S3](https://github.com/kanboard/plugin-s3)
- [Budget planning](https://github.com/kanboard/plugin-budget)
- [User timetables](https://github.com/kanboard/plugin-timetable)
- [Subtask Forecast](https://github.com/kanboard/plugin-subtask-forecast)
- [Automatic Action example](https://github.com/kanboard/plugin-example-automatic-action)
- [Theme plugin example](https://github.com/kanboard/plugin-example-theme)
- [CSS plugin example](https://github.com/kanboard/plugin-example-css)