Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions samples/Migration.php.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace FacturaScripts\[[NAME_SPACE]]\Migration;

use FacturaScripts\Core\Template\MigrationClass;

/**
* Clase de migración para realizar cambios en la base de datos de forma segura.
* Se ejecuta automáticamente tras instalar o actualizar el plugin.
*
* Más información: https://facturascripts.com/publicaciones/migraciones-de-tablas
*/
class [[NAME]] extends MigrationClass
{
/**
* Identificador único de la migración.
* Debe ser descriptivo e incluir versión o fecha.
*/
const MIGRATION_NAME = '[[MIGRATION_NAME]]';

/**
* Ejecuta la lógica de la migración
*/
public function run(): void
{
// Tu lógica aquí
// if (!$this->db()->tableExists('mi_tabla')) {
// return;
// }
}
}
74 changes: 74 additions & 0 deletions src/Command/Migration/MigrationCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/**
* @author fsmaker
*/

namespace fsmaker\Command\Migration;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use fsmaker\Console\BaseCommand;
use fsmaker\InitEditor;
use fsmaker\Utils;

#[AsCommand(
name: 'migration',
description: 'Crea una nueva migración'
)]
class MigrationCommand extends BaseCommand
{
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->requirePlugin()) {
return Command::FAILURE;
}

$name = Utils::prompt(
label: 'Nombre de la migración',
placeholder: 'Ej: FixTablaUsuarios',
hint: 'El nombre debe empezar por mayúscula y solo puede contener letras, números y guiones bajos.',
regex: '/^[A-Z][a-zA-Z0-9_]*$/',
errorMessage: 'Inválido, debe empezar por mayúscula y solo puede contener letras, números y guiones bajos.'
);

$this->createMigration($name);

return Command::SUCCESS;
}

private function createMigration(string $name): void
{
$folder = 'Migration/';
Utils::createFolder($folder);

$fileName = $folder . $name . '.php';
if (file_exists($fileName)) {
Utils::echo("* La migración " . $name . " YA EXISTE.\n");
return;
}

$samplePath = dirname(__DIR__, 3) . "/samples/Migration.php.sample";
$sample = file_get_contents($samplePath);

$migrationNameConst = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $name)) . '_' . date('Y_m_d');
$template = str_replace(
['[[NAME]]', '[[NAME_SPACE]]', '[[MIGRATION_NAME]]'],
[$name, Utils::getNamespace(), $migrationNameConst],
$sample
);
file_put_contents($fileName, $template);
Utils::echo('* ' . $fileName . " -> OK.\n");

$newContentUse = InitEditor::addUse('use FacturaScripts\Core\Migrations;');
if ($newContentUse) {
InitEditor::setInitContent($newContentUse);
}

$newContentFunc = InitEditor::addToFunction('update', 'Migrations::runPluginMigration(new Migration\\' . $name . '());', true);
if ($newContentFunc) {
InitEditor::setInitContent($newContentFunc);
}
}
}
1 change: 1 addition & 0 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ private function getCommands(): array
new \fsmaker\Command\Generator\ZipCommand(),
new \fsmaker\Command\Init\InitCommand(),
new \fsmaker\Command\List\ListCommand(),
new \fsmaker\Command\Migration\MigrationCommand(),
new \fsmaker\Command\Model\ModelCommand(),
new \fsmaker\Command\Plugin\PluginCommand(),
new \fsmaker\Command\Test\TestCommand(),
Expand Down
28 changes: 21 additions & 7 deletions src/InitEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,17 @@ public static function addUse(string $useInstruction): ?string
}

/**
* Devuelve el contenido del fichero agregandole la linea introducida por `str`. Si quieres agregarla solo si no existe puedes colocar a true `checkIfNotExists`
* Devuelve el contenido del fichero agregandole la linea introducida por `str` a la función indicada. Si quieres agregarla solo si no existe puedes colocar a true `checkIfNotExists`
* - Esta función si que escribe comentarios en la terminal
* @param string $functionName
* @param string $instructionStr
* @param bool $checkIfNotExists revisa si existe esa linea de código
* @return ?string Si no ha sido exitosa la operación devuelve false si no pues el string modificado
*/
public static function addToInitFunction(string $instructionStr, bool $checkIfNotExists = false): ?string
public static function addToFunction(string $functionName, string $instructionStr, bool $checkIfNotExists = false): ?string
{
// obtener el diagnostico general
$analysis = self::detectValidInitFunction();
$analysis = self::detectValidFunction($functionName);

// si algo va mal
if (!$analysis['isValid']) {
Expand Down Expand Up @@ -114,11 +115,24 @@ public static function addToInitFunction(string $instructionStr, bool $checkIfNo
return mb_substr($info['initContent'], 0, $info['functionStart']) . $body . mb_substr($info['initContent'], $info['functionEnd']);
}

/**
* Devuelve el contenido del fichero agregandole la linea introducida por `str` a la función `init`. Si quieres agregarla solo si no existe puedes colocar a true `checkIfNotExists`
* - Esta función si que escribe comentarios en la terminal
* @param string $instructionStr
* @param bool $checkIfNotExists revisa si existe esa linea de código
* @return ?string Si no ha sido exitosa la operación devuelve false si no pues el string modificado
*/
public static function addToInitFunction(string $instructionStr, bool $checkIfNotExists = false): ?string
{
return self::addToFunction('init', $instructionStr, $checkIfNotExists);
}

/**
* Esta función analiza el fichero y detecta si está correcto y se puede agregar funciones. Devuelve información útil.
* @param string $functionName
* @return array {isValid: bool, info: string|array}
*/
public static function detectValidInitFunction(): array
public static function detectValidFunction(string $functionName): array
{
$str = self::getInitContent();

Expand All @@ -130,16 +144,16 @@ public static function detectValidInitFunction(): array
}

$error = '';
$words = ['public', 'function', 'init', '(', ')', ':', 'void', '{'];
$words = ['public', 'function', $functionName, '(', ')', ':', 'void', '{'];

// comprobar si solo existe una función init
$matches = self::getSentenceMatches(self::removeSpaces($str), implode($words));

if (count($matches) !== 1) {
if (count($matches) > 1) {
$error = '* Error(Init.php): Init mal formado. Existe más de una coincidencia de: "public function init(): void{".\n';
$error = '* Error(Init.php): Init mal formado. Existe más de una coincidencia de: "public function ' . $functionName . '(): void{".\n';
} else {// $matches < 1
$error = '* Error(Init.php): Init mal formado. No se ha podido encontrar "public function init(): void{".\n';
$error = '* Error(Init.php): Init mal formado. No se ha podido encontrar "public function ' . $functionName . '(): void{".\n';
}
return [
'isValid' => false,
Expand Down
Loading