Interfaz de línea de comandos
1Presentación
A menudo resulta útil escribir scripts que se ejecuten desde la línea de comandos. Esto es muy fácil de hacer en PHP puro, pero luego hay que inicializar manualmente el log, las fuentes de datos, el autoloader, la inyección de dependencias...
Por ello, Temma ofrece la funcionalidad Comma (COMmand-line MAnager), que realiza todas las inicializaciones necesarias antes de ejecutar el código solicitado.
Un script se ejecuta llamando al programa bin/comma, pasándole como parámetros
el nombre del objeto y del método que se van a ejecutar, así como los parámetros adicionales que espera ese método.
La forma canónica es objeto/método, como una URL de Temma. El nombre del método también puede
separarse del nombre del objeto con un espacio, dos puntos (:, como en los comandos de Symfony) o
dos puntos dobles (::, como en las llamadas estáticas de PHP); estas formas son equivalentes.
El código que se ejecuta puede ser completamente autónomo (haciendo su trabajo a partir de las opciones proporcionadas),
o entrar en comunicación interactiva con el usuario.
Algunos ejemplos imaginarios:
Nuevos datos enviados al CRM
Introduce la ruta del archivo a importar: /tmp/import.json
Importación completada
Por defecto, los comandos ejecutables se almacenan en el directorio cli/ del proyecto. Sin embargo, puedes colocarlos donde quieras dentro de las rutas de inclusión, eventualmente usando un namespace.
Al usar un namespace, debes encerrar el nombre del objeto entre comillas o apóstrofos.
Por ejemplo:
Nuevos datos enviados al CRM
Introduce la ruta del archivo a importar: /tmp/import.json
Importación completada
Comandos proporcionados por Temma
Temma proporciona varios comandos, cuya documentación puede encontrarse en la sección "Helpers":
- \Temma\Cli\Temma: Para gestionar el framework: información de versión, actualización, servidor de desarrollo.
- \Temma\Cli\Cache: Para vaciar la caché.
- \Temma\Cli\User: Para gestionar usuarios (compatible con el plugin/controlador Auth, el atributo Auth y el plugin Api).
Cuando un nombre de controlador no empieza por una barra invertida y no corresponde a ninguna clase del proyecto, se busca automáticamente en el namespace \Temma\Cli. Así, es posible escribir bin/comma Cache/clear en lugar de bin/comma '\Temma\Cli\Cache' clear (una clase del proyecto con el mismo nombre tiene prioridad).
2Documentación
Al escribir bin/comma o bin/comma help, puedes ver la documentación general de Comma:
Si escribes bin/comma help seguido del nombre de un controlador, verás una lista de las acciones del controlador, con su documentación asociada:
Si añades el nombre de una acción, solo verás su documentación:
3Controladores
Los objetos ejecutados por Comma son controladores idénticos a los usados por Temma en respuesta a las peticiones HTTP, salvo que deben almacenarse en el directorio cli/ (y no en controllers/).
Hay muchas similitudes:
- Las acciones pueden recibir un número variable de parámetros, con parámetros opcionales (con un valor por defecto).
- Los métodos de inicialización __wakeup() y de finalización __sleep() se ejecutan respectivamente antes y después de la ejecución de la acción.
- Si no se indica ningún nombre de método en la línea de comandos, se llama a la acción raíz __invoke(). Esta acción no puede recibir parámetros.
- Si se define una acción por defecto __call() en el controlador, se ejecutará para todas las acciones solicitadas que no tengan un método equivalente.
- Si se define una acción proxy __proxy() en el controlador, se ejecutará siempre, sea cual sea la acción llamada.
- Los atributos definidos en controladores y acciones se ejecutan (siempre que puedan funcionar en un entorno de línea de comandos, y no en un entorno web).
- El archivo de configuración etc/temma.php se lee y su contenido se pone a disposición mediante el objeto $this->_config.
- El componente de inyección de dependencias se genera, y está disponible de la misma forma (escribiendo $this->_loader).
- Las fuentes de datos se generan, y están disponibles ya sea escribiéndolas directamente (por ejemplo $this->db), o pasando por el componente de inyección de dependencias (por ejemplo $this->_loader->dataSources->db o $this->_loader->dataSources['db-read']).
- También pueden usarse los DAO.
Pero también hay varias diferencias:
- No existe sistema de rutas, ni siquiera simplificado (no es posible llamar a un controlador con un nombre distinto del suyo).
- No se ejecuta ningún plugin.
- No hay vistas.
- El objeto $this->_request solo contiene los parámetros proporcionados en la línea de comandos.
4Parámetros
Los parámetros esperados por las acciones pueden pasarse en la línea de comandos de dos maneras, que pueden combinarse: parámetros nombrados y parámetros posicionales.
Los parámetros nombrados se pasan añadiendo el prefijo --, seguido del signo igual (=) y del valor asociado. Se asocian a los parámetros del método según sus nombres.
Si el valor contiene espacios, puede encerrarse entre comillas (") o apóstrofos (').
Si un parámetro nombrado se pasa sin valor, se procesará como un booleano con valor true.
Los parámetros posicionales rellenan los parámetros del método de izquierda a derecha. Pueden escribirse como una URL de Temma (objeto/método/valor1/valor2, en cuyo caso los valores no pueden contener barras) o como simples argumentos de línea de comandos (objeto/método valor1 valor2).
Un valor posicional que empiece por un guion debe ir precedido del marcador estándar de fin de opciones --: bin/comma Math/add 3 -- -5
5Ejemplo
Por ejemplo, podrías crear un script para añadir un usuario a la base de datos.
Este script podría llamarse así:
La misma llamada, con parámetros posicionales:
Podríamos imaginar un parámetro opcional, para indicar que el usuario es administrador:
En términos concretos, Comma instanciará el objeto User, y luego llamará a su método add(), pasándole los parámetros.
El objeto User debe almacenarse en un archivo llamado User.php,
ubicado en el directorio cli/ del proyecto.
Este objeto debe heredar del objeto \Temma\Web\Controller.
El código de este objeto podría ser:
class User extends \Temma\Web\Controller {
/** Creación de un Data Access Object automático. */
protected $_temmaAutoDao = true;
/**
* Añadir usuario.
* @param string $name Nombre del usuario.
* @param string $email Dirección de correo electrónico del usuario.
* @param bool $admin (opcional) Permisos de administrador. Falso por defecto.
*/
public function add(string $name, string $email, bool $admin=false) {
// añade el usuario a la base de datos
$id = $this->_dao->create([
'name' => $name,
'email' => $email,
'roles' => $admin ? 'admin' : '',
]);
// mensaje
print("Usuario creado con el identificador '$id'.\n");
}
}
6Configuración
Por defecto, los scripts de línea de comandos cargan la configuración presente en el archivo etc/temma.php. Es posible indicar la ruta a otro archivo usando el parámetro conf.
Este parámetro debe colocarse antes del nombre del controlador.
Por ejemplo:
Ten en cuenta que es posible indicar un archivo fuera del árbol del proyecto, pero eso no cambiará las rutas usadas hacia los distintos directorios. Por ejemplo, el plugin Language seguirá buscando sus archivos en etc/lang/.
7Rutas de inclusión
Los scripts ejecutados con Comma tienen el directorio lib/ del proyecto añadido a sus rutas de inclusión. Pueden añadirse rutas adicionales con el parámetro inc.
Al igual que con el parámetro conf, este parámetro debe colocarse antes del nombre del controlador.
Por ejemplo:
8Log
Por defecto, los scripts de línea de comandos escriben sus logs en la salida de error.
Si así se indica en el archivo etc/temma.php, los logs también pueden escribirse en el archivo log/temma.log.
Para desactivar la escritura en la salida de error, usa el parámetro nostderr.
Al igual que con los parámetros conf e inc, este parámetro debe colocarse antes del nombre del controlador.
Ejemplo:
9Interfaz
La interfaz de usuario es completamente distinta de la de los controladores web. Los scripts de línea de comandos interactúan escribiendo en su salida estándar, y recuperan lo que el usuario introduce leyendo desde su entrada estándar.
Temma proporciona dos helpers útiles en estas condiciones:
- \Temma\Utils\Ansi: proporciona métodos para mejorar la visualización de la información escrita por tu código.
- \Temma\Utils\Term: proporciona funcionalidades para interactuar más fácilmente con la terminal.