diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b337c2..757775a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ dev - [ ] add module to check deprecated PHP function - [ ] add module to check directory structure - [ ] write documentation of php class +- add module to use external php-cs-fixer 0.3 - 2021.10.29 - use of xmlTag to generate dcstore.xml contents diff --git a/_admin.php b/_admin.php index bd1497d..d789ea9 100644 --- a/_admin.php +++ b/_admin.php @@ -1,16 +1,15 @@ blog->settings->addNamespace('improve'); $core->addBehavior('adminDashboardFavorites', ['ImproveBehaviors', 'adminDashboardFavorites']); @@ -22,6 +21,7 @@ $core->addBehavior('improveAddAction', ['ImproveActionGitshields', 'create']); $core->addBehavior('improveAddAction', ['ImproveActionLicensefile', 'create']); //$core->addBehavior('improveAddAction', ['ImproveActionLicense', 'create']); $core->addBehavior('improveAddAction', ['ImproveActionNewline', 'create']); +$core->addBehavior('improveAddAction', ['ImproveActionPhpcsfixer', 'create']); $core->addBehavior('improveAddAction', ['ImproveActionPhpheader', 'create']); $core->addBehavior('improveAddAction', ['ImproveActionTab', 'create']); $core->addBehavior('improveAddAction', ['ImproveActionZip', 'create']); @@ -49,4 +49,4 @@ class ImproveBehaviors ] ); } -} \ No newline at end of file +} diff --git a/_prepend.php b/_prepend.php index 6fb4e52..d30d2aa 100644 --- a/_prepend.php +++ b/_prepend.php @@ -1,23 +1,22 @@ 'class.improve.php', - 'ImproveAction' => 'class.improve.action.php', + 'Improve' => 'class.improve.php', + 'ImproveAction' => 'class.improve.action.php', 'ImproveActionDcdeprecated' => 'lib.improve.action.dcdeprecated.php', 'ImproveActionDcstore' => 'lib.improve.action.dcstore.php', @@ -25,11 +24,12 @@ $improve_libs = [ 'ImproveActionGitshields' => 'lib.improve.action.gitshields.php', 'ImproveActionLicensefile' => 'lib.improve.action.licensefile.php', 'ImproveActionNewline' => 'lib.improve.action.php', + 'ImproveActionPhpcsfixer' => 'lib.improve.action.phpcsfixer.php', 'ImproveActionPhpheader' => 'lib.improve.action.phpheader.php', 'ImproveActionTab' => 'lib.improve.action.php', 'ImproveActionZip' => 'lib.improve.action.zip.php', 'ImproveZipFileZip' => 'lib.improve.action.zip.php' ]; -foreach($improve_libs as $class => $file) { +foreach ($improve_libs as $class => $file) { $__autoload[$class] = dirname(__FILE__) . '/inc/' . $file; -} \ No newline at end of file +} diff --git a/inc/dc.phpcsfixer.rules.php b/inc/dc.phpcsfixer.rules.php new file mode 100644 index 0000000..6cc8a0b --- /dev/null +++ b/inc/dc.phpcsfixer.rules.php @@ -0,0 +1,65 @@ +exclude('node_modules') + ->exclude('vendor') + ->in(__DIR__); + +$config = new PhpCsFixer\Config(); + +return $config + ->setRules([ + '@PSR2' => true, + 'array_indentation' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => [ + 'default' => 'align_single_space_minimal', + 'operators' => [ + '=>' => 'align_single_space_minimal', + ] + ], + 'blank_line_before_statement' => true, + 'braces' => ['allow_single_line_closure' => true], + 'cast_spaces' => true, + 'combine_consecutive_unsets' => true, + 'concat_space' => ['spacing' => 'one'], + 'linebreak_after_opening_tag' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_break_comment' => false, + 'no_extra_blank_lines' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_whitespace_in_blank_line' => true, + 'no_spaces_around_offset' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'normalize_index_brace' => true, + 'phpdoc_indent' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'ternary_to_null_coalescing' => true, + 'trailing_comma_in_multiline' => false, + 'trim_array_spaces' => true, + ]) + ->setFinder($finder); diff --git a/inc/lib.improve.action.phpcsfixer.php b/inc/lib.improve.action.phpcsfixer.php new file mode 100644 index 0000000..9ba38e7 --- /dev/null +++ b/inc/lib.improve.action.phpcsfixer.php @@ -0,0 +1,110 @@ + 'OK.', + 1 => 'General error (or PHP minimal requirement not matched).', + 4 => 'Some files have invalid syntax (only in dry-run mode).', + 8 => 'Some files need fixing (only in dry-run mode).', + 16 => 'Configuration error of the application.', + 32 => 'Configuration error of a Fixer.', + 64 => 'Exception raised within the application' + ]; + + protected function init(): bool + { + $this->setProperties([ + 'id' => 'phpcsfixer', + 'name' => __('PHP CS Fixer'), + 'desc' => __('Fix PSR coding style using Php CS Fixer'), + 'priority' => 920, + 'config' => true, + 'types' => ['plugin', 'theme'] + ]); + + return true; + } + + public function isConfigured(): bool + { + return !empty($this->getSetting('phpcsf_path')); + } + + public function configure($url): ?string + { + if (!empty($_POST['save'])) { + $this->setSettings([ + 'phpexe_path' => !empty($_POST['phpexe_path']) ? $_POST['phpexe_path'] : '', + 'phpcsf_path' => !empty($_POST['phpcsf_path']) ? $_POST['phpcsf_path'] : '' + ]); + $this->redirect($url); + } + + return + '

' . sprintf( + __('You must have installed %s to use this tool'), + 'php-cs-fixer' + ) . '

' . + '

' . + '

' . + '

' . + __('If this server is under unix, leave it empty.') . ' ' . + __('If this server is under Windows, put here directory to php executable (without executable file name).') . + ' C:\path_to\php

' . + '

' . + '

' . + '

' . __('Do not add file name to the end of path.') . ' \path_to\tools\php-cs-fixer\vendor\friendsofphp\php-cs-fixer

'; + } + + public function closeModule(): ?bool + { + $phpexe_path = path::real($this->getSetting('phpexe_path')); + if (!empty($phpexe_path)) { + $phpexe_path .= '/'; + } + $phpcsf_path = path::real($this->getSetting('phpcsf_path')); + + $command = sprintf( + '%sphp %s/php-cs-fixer fix %s --config=%s/dc.phpcsfixer.rules.php', + $phpexe_path, + $phpcsf_path, + $this->module['sroot'], + dirname(__FILE__) + ); + + try { + exec($command, $output, $error); + if (empty($output)) { + if (isset(self::$errors[$error])) { + $this->setError(self::$errors[$error]); + + return false; + } + + throw new Exception('oops'); + } + $this->setSuccess(sprintf('
%s
', implode('
', $output))); + + return true; + } catch (Exception $e) { + $this->setError(__('Failed to run php-cs-fixer')); + + return false; + } + } +}