From 5427abe032e723649b5ba19a4625b87d8505394f Mon Sep 17 00:00:00 2001 From: Patrizio Bekerle Date: Wed, 19 Oct 2022 14:26:45 +0200 Subject: [PATCH] Add linter and fixes --- .gitignore | 2 + .php-cs-fixer.dist.php | 25 + .php_cs.dist | 22 + 3rdparty/finediff/finediff.php | 505 +-- appinfo/app.php | 4 +- appinfo/application.php | 14 +- appinfo/routes.php | 4 +- composer.json | 27 + composer.lock | 3106 +++++++++++++++++ controller/noteapicontroller.php | 210 +- docker/qownnotesapi.config.php | 2 +- lib/capabilities.php | 35 +- phpstan.neon | 16 + psalm.xml | 39 + tests/integration/AppTest.php | 17 +- .../unit/controller/NoteApiControllerTest.php | 204 +- 16 files changed, 3782 insertions(+), 450 deletions(-) create mode 100644 .php-cs-fixer.dist.php create mode 100644 .php_cs.dist create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 phpstan.neon create mode 100644 psalm.xml diff --git a/.gitignore b/.gitignore index 5160d66..e834153 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ docker/nextcloud/certificates/* docker/owncloud/certificates/* *.gz *.db* +*.cache +vendor diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..f89ebed --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,25 @@ +in(__DIR__) + ->exclude('var') +; + +$config = new PhpCsFixer\Config(); +$config->setRules([ + '@Symfony' => true, + '@PHP70Migration' => true, + '@PHP71Migration' => true, + '@PHP73Migration' => true, + '@DoctrineAnnotation' => true, + 'doctrine_annotation_array_assignment' => ['operator' => '='], + 'yoda_style' => false, + 'strict_comparison' => true, + 'strict_param' => true, + 'declare_strict_types' => true, + 'method_argument_space' => ['on_multiline' => 'ignore'], +]) + ->setRiskyAllowed(true) + ->setFinder($finder); + +return $config; diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 0000000..3a884c5 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,22 @@ +in(__DIR__) + ->exclude('var') +; + +return PhpCsFixer\Config::create() + ->setRules([ + '@Symfony' => true, + '@PHP70Migration' => true, + '@PHP71Migration' => true, + '@PHP73Migration' => true, + 'array_syntax' => ['syntax' => 'short'], + 'yoda_style' => false, + 'strict_comparison' => true, + 'strict_param' => true, + 'declare_strict_types' => true, + ]) + ->setRiskyAllowed(true) + ->setFinder($finder) +; diff --git a/3rdparty/finediff/finediff.php b/3rdparty/finediff/finediff.php index 9b4d48c..554ea9d 100644 --- a/3rdparty/finediff/finediff.php +++ b/3rdparty/finediff/finediff.php @@ -1,6 +1,8 @@ optimize()?) */ - -abstract class FineDiffOp { +abstract class FineDiffOp +{ abstract public function getFromLen(); + abstract public function getToLen(); + abstract public function getOpcode(); } -class FineDiffDeleteOp extends FineDiffOp { - public function __construct($len) { +class FineDiffDeleteOp extends FineDiffOp +{ + public function __construct($len) + { $this->fromLen = $len; } - public function getFromLen() { + + public function getFromLen() + { return $this->fromLen; } - public function getToLen() { + + public function getToLen() + { return 0; } - public function getOpcode() { - if ( $this->fromLen === 1 ) { + + public function getOpcode() + { + if ($this->fromLen === 1) { return 'd'; } + return "d{$this->fromLen}"; } } -class FineDiffInsertOp extends FineDiffOp { - public function __construct($text) { +class FineDiffInsertOp extends FineDiffOp +{ + public function __construct($text) + { $this->text = $text; } - public function getFromLen() { + + public function getFromLen() + { return 0; } - public function getToLen() { + + public function getToLen() + { return strlen($this->text); } - public function getText() { + + public function getText() + { return $this->text; } - public function getOpcode() { + + public function getOpcode() + { $to_len = strlen($this->text); - if ( $to_len === 1 ) { + if ($to_len === 1) { return "i:{$this->text}"; } + return "i{$to_len}:{$this->text}"; } } -class FineDiffReplaceOp extends FineDiffOp { - public function __construct($fromLen, $text) { +class FineDiffReplaceOp extends FineDiffOp +{ + public function __construct($fromLen, $text) + { $this->fromLen = $fromLen; $this->text = $text; } - public function getFromLen() { + + public function getFromLen() + { return $this->fromLen; } - public function getToLen() { + + public function getToLen() + { return strlen($this->text); } - public function getText() { + + public function getText() + { return $this->text; } - public function getOpcode() { - if ( $this->fromLen === 1 ) { + + public function getOpcode() + { + if ($this->fromLen === 1) { $del_opcode = 'd'; - } - else { + } else { $del_opcode = "d{$this->fromLen}"; } $to_len = strlen($this->text); - if ( $to_len === 1 ) { + if ($to_len === 1) { return "{$del_opcode}i:{$this->text}"; } + return "{$del_opcode}i{$to_len}:{$this->text}"; } } -class FineDiffCopyOp extends FineDiffOp { - public function __construct($len) { +class FineDiffCopyOp extends FineDiffOp +{ + public function __construct($len) + { $this->len = $len; } - public function getFromLen() { + + public function getFromLen() + { return $this->len; } - public function getToLen() { + + public function getToLen() + { return $this->len; } - public function getOpcode() { - if ( $this->len === 1 ) { + + public function getOpcode() + { + if ($this->len === 1) { return 'c'; } + return "c{$this->len}"; } - public function increase($size) { + + public function increase($size) + { return $this->len += $size; } } /** - * FineDiff ops + * FineDiff ops. * * Collection of ops */ -class FineDiffOps { - public function appendOpcode($opcode, $from, $from_offset, $from_len) { - if ( $opcode === 'c' ) { +class FineDiffOps +{ + public function appendOpcode($opcode, $from, $from_offset, $from_len) + { + if ($opcode === 'c') { $edits[] = new FineDiffCopyOp($from_len); - } - else if ( $opcode === 'd' ) { + } elseif ($opcode === 'd') { $edits[] = new FineDiffDeleteOp($from_len); - } - else /* if ( $opcode === 'i' ) */ { + } else { /* if ( $opcode === 'i' ) */ $edits[] = new FineDiffInsertOp(substr($from, $from_offset, $from_len)); } } - public $edits = array(); + public $edits = []; } /** - * FineDiff class + * FineDiff class. * * TODO: Document - * */ -class FineDiff { - +class FineDiff +{ /**------------------------------------------------------------------------ * * Public section @@ -213,46 +260,49 @@ class FineDiff { * a particular stack tailored to the specific content of a document can * be passed. */ - public function __construct($from_text = '', $to_text = '', $granularityStack = null) { + public function __construct($from_text = '', $to_text = '', $granularityStack = null) + { // setup stack for generic text documents by default $this->granularityStack = $granularityStack ? $granularityStack : FineDiff::$characterGranularity; - $this->edits = array(); + $this->edits = []; $this->from_text = $from_text; $this->doDiff($from_text, $to_text); } - public function getOps() { + public function getOps() + { return $this->edits; } - public function getOpcodes() { - $opcodes = array(); - foreach ( $this->edits as $edit ) { + public function getOpcodes() + { + $opcodes = []; + foreach ($this->edits as $edit) { $opcodes[] = $edit->getOpcode(); } + return implode('', $opcodes); } - public function renderDiffToHTML() { + public function renderDiffToHTML() + { $in_offset = 0; ob_start(); - foreach ( $this->edits as $edit ) { + foreach ($this->edits as $edit) { $n = $edit->getFromLen(); - if ( $edit instanceof FineDiffCopyOp ) { + if ($edit instanceof FineDiffCopyOp) { FineDiff::renderDiffToHTMLFromOpcode('c', $this->from_text, $in_offset, $n); - } - else if ( $edit instanceof FineDiffDeleteOp ) { + } elseif ($edit instanceof FineDiffDeleteOp) { FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); - } - else if ( $edit instanceof FineDiffInsertOp ) { + } elseif ($edit instanceof FineDiffInsertOp) { FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); - } - else /* if ( $edit instanceof FineDiffReplaceOp ) */ { + } else { /* if ( $edit instanceof FineDiffReplaceOp ) */ FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); } $in_offset += $n; } + return ob_get_clean(); } @@ -260,44 +310,54 @@ public function renderDiffToHTML() { * Return an opcodes string describing the diff between a "From" and a * "To" string */ - public static function getDiffOpcodes($from, $to, $granularities = null) { + public static function getDiffOpcodes($from, $to, $granularities = null) + { $diff = new FineDiff($from, $to, $granularities); + return $diff->getOpcodes(); } /**------------------------------------------------------------------------ * Return an iterable collection of diff ops from an opcodes string */ - public static function getDiffOpsFromOpcodes($opcodes) { + public static function getDiffOpsFromOpcodes($opcodes) + { $diffops = new FineDiffOps(); - FineDiff::renderFromOpcodes(null, $opcodes, array($diffops,'appendOpcode')); + FineDiff::renderFromOpcodes(null, $opcodes, [$diffops, 'appendOpcode']); + return $diffops->edits; } /**------------------------------------------------------------------------ * Re-create the "To" string from the "From" string and an "Opcodes" string */ - public static function renderToTextFromOpcodes($from, $opcodes) { + public static function renderToTextFromOpcodes($from, $opcodes) + { ob_start(); - FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderToTextFromOpcode')); + FineDiff::renderFromOpcodes($from, $opcodes, ['FineDiff', 'renderToTextFromOpcode']); + return ob_get_clean(); } /**------------------------------------------------------------------------ * Render the diff to an HTML string -- UTF8 unsafe */ - public static function renderDiffToHTMLFromOpcodes($from, $opcodes) { + public static function renderDiffToHTMLFromOpcodes($from, $opcodes) + { ob_start(); - FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + FineDiff::renderFromOpcodes($from, $opcodes, ['FineDiff', 'renderDiffToHTMLFromOpcode']); + return ob_get_clean(); } /**------------------------------------------------------------------------ * Render the diff to an HTML string -- UTF8 safe */ - public static function renderUTF8DiffToHTMLFromOpcodes($from, $opcodes) { + public static function renderUTF8DiffToHTMLFromOpcodes($from, $opcodes) + { ob_start(); - FineDiff::renderUTF8FromOpcode($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + FineDiff::renderUTF8FromOpcode($from, $opcodes, ['FineDiff', 'renderDiffToHTMLFromOpcode']); + return ob_get_clean(); } @@ -305,31 +365,29 @@ public static function renderUTF8DiffToHTMLFromOpcodes($from, $opcodes) { * Generic opcodes parser, user must supply callback for handling * single opcode */ - public static function renderFromOpcodes($from, $opcodes, $callback) { - if ( !is_callable($callback) ) { + public static function renderFromOpcodes($from, $opcodes, $callback) + { + if (!is_callable($callback)) { return; } $opcodes_len = strlen($opcodes); $from_offset = $opcodes_offset = 0; - while ( $opcodes_offset < $opcodes_len ) { + while ($opcodes_offset < $opcodes_len) { $opcode = substr($opcodes, $opcodes_offset, 1); - $opcodes_offset++; + ++$opcodes_offset; $n = intval(substr($opcodes, $opcodes_offset)); - if ( $n ) { + if ($n) { $opcodes_offset += strlen(strval($n)); - } - else { + } else { $n = 1; } - if ( $opcode === 'c' ) { // copy n characters from source + if ($opcode === 'c') { // copy n characters from source call_user_func($callback, 'c', $from, $from_offset, $n, ''); $from_offset += $n; - } - else if ( $opcode === 'd' ) { // delete n characters from source + } elseif ($opcode === 'd') { // delete n characters from source call_user_func($callback, 'd', $from, $from_offset, $n, ''); $from_offset += $n; - } - else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + } else { /* if ( $opcode === 'i' ) */ // insert n characters from opcodes call_user_func($callback, 'i', $opcodes, $opcodes_offset + 1, $n); $opcodes_offset += 1 + $n; } @@ -340,50 +398,56 @@ public static function renderFromOpcodes($from, $opcodes, $callback) { * Generic opcodes parser, user must supply callback for handling * single opcode */ - private static function renderUTF8FromOpcode($from, $opcodes, $callback) { - if ( !is_callable($callback) ) { + private static function renderUTF8FromOpcode($from, $opcodes, $callback) + { + if (!is_callable($callback)) { return; } $from_len = strlen($from); $opcodes_len = strlen($opcodes); $from_offset = $opcodes_offset = 0; $last_to_chars = ''; - while ( $opcodes_offset < $opcodes_len ) { + while ($opcodes_offset < $opcodes_len) { $opcode = substr($opcodes, $opcodes_offset, 1); - $opcodes_offset++; + ++$opcodes_offset; $n = intval(substr($opcodes, $opcodes_offset)); - if ( $n ) { + if ($n) { $opcodes_offset += strlen(strval($n)); - } - else { + } else { $n = 1; } - if ( $opcode === 'c' || $opcode === 'd' ) { + if ($opcode === 'c' || $opcode === 'd') { $beg = $from_offset; $end = $from_offset + $n; - while ( $beg > 0 && (ord($from[$beg]) & 0xC0) === 0x80 ) { $beg--; } - while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } - if ( $opcode === 'c' ) { // copy n characters from source + while ($beg > 0 && (ord($from[$beg]) & 0xC0) === 0x80) { + --$beg; + } + while ($end < $from_len && (ord($from[$end]) & 0xC0) === 0x80) { + ++$end; + } + if ($opcode === 'c') { // copy n characters from source call_user_func($callback, 'c', $from, $beg, $end - $beg, ''); $last_to_chars = substr($from, $from, $beg, $end - $beg); - } - else /* if ( $opcode === 'd' ) */ { // delete n characters from source + } else { /* if ( $opcode === 'd' ) */ // delete n characters from source call_user_func($callback, 'd', $from, $beg, $end - $beg, ''); } $from_offset += $n; - } - else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes - $opcodes_offset += 1; - if ( strlen($last_to_chars) > 0 && (ord($opcodes[$opcodes_offset]) & 0xC0) === 0x80 ) { + } else { /* if ( $opcode === 'i' ) */ // insert n characters from opcodes + ++$opcodes_offset; + if (strlen($last_to_chars) > 0 && (ord($opcodes[$opcodes_offset]) & 0xC0) === 0x80) { $beg = strlen($last_to_chars) - 1; - while ( $beg > 0 && (ord($last_to_chars[$beg]) & 0xC0) === 0x80 ) { $beg--; } + while ($beg > 0 && (ord($last_to_chars[$beg]) & 0xC0) === 0x80) { + --$beg; + } $prefix = substr($last_to_chars, $beg); } else { $prefix = ''; } $end = $from_offset; - while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } - $toInsert = $prefix . substr($opcodes, $opcodes_offset, $n) . substr($from, $end, $end - $from_offset); + while ($end < $from_len && (ord($from[$end]) & 0xC0) === 0x80) { + ++$end; + } + $toInsert = $prefix.substr($opcodes, $opcodes_offset, $n).substr($from, $end, $end - $from_offset); call_user_func($callback, 'i', $toInsert, 0, strlen($toInsert)); $opcodes_offset += $n; $last_to_chars = $toInsert; @@ -392,37 +456,36 @@ private static function renderUTF8FromOpcode($from, $opcodes, $callback) { } /** - * Stock granularity stacks and delimiters + * Stock granularity stacks and delimiters. */ - - const paragraphDelimiters = "\n\r"; - public static $paragraphGranularity = array( - FineDiff::paragraphDelimiters - ); - const sentenceDelimiters = ".\n\r"; - public static $sentenceGranularity = array( + public const paragraphDelimiters = "\n\r"; + public static $paragraphGranularity = [ + FineDiff::paragraphDelimiters, + ]; + public const sentenceDelimiters = ".\n\r"; + public static $sentenceGranularity = [ FineDiff::paragraphDelimiters, - FineDiff::sentenceDelimiters - ); - const wordDelimiters = " \t.\n\r"; - public static $wordGranularity = array( + FineDiff::sentenceDelimiters, + ]; + public const wordDelimiters = " \t.\n\r"; + public static $wordGranularity = [ FineDiff::paragraphDelimiters, FineDiff::sentenceDelimiters, - FineDiff::wordDelimiters - ); - const characterDelimiters = ""; - public static $characterGranularity = array( + FineDiff::wordDelimiters, + ]; + public const characterDelimiters = ''; + public static $characterGranularity = [ FineDiff::paragraphDelimiters, FineDiff::sentenceDelimiters, FineDiff::wordDelimiters, - FineDiff::characterDelimiters - ); + FineDiff::characterDelimiters, + ]; - public static $textStack = array( - ".", + public static $textStack = [ + '.', " \t.\n\r", - "" - ); + '', + ]; /**------------------------------------------------------------------------ * @@ -433,13 +496,14 @@ private static function renderUTF8FromOpcode($from, $opcodes, $callback) { /** * Entry point to compute the diff. */ - private function doDiff($from_text, $to_text) { + private function doDiff($from_text, $to_text) + { $this->last_edit = false; $this->stackpointer = 0; $this->from_text = $from_text; $this->from_offset = 0; // can't diff without at least one granularity specifier - if ( empty($this->granularityStack) ) { + if (empty($this->granularityStack)) { return; } $this->_processGranularity($from_text, $to_text); @@ -452,23 +516,23 @@ private function doDiff($from_text, $to_text) { * Incrementally increasing the granularity is key to compute the * overall diff in a very efficient way. */ - private function _processGranularity($from_segment, $to_segment) { + private function _processGranularity($from_segment, $to_segment) + { $delimiters = $this->granularityStack[$this->stackpointer++]; $has_next_stage = $this->stackpointer < count($this->granularityStack); - foreach ( FineDiff::doFragmentDiff($from_segment, $to_segment, $delimiters) as $fragment_edit ) { + foreach (FineDiff::doFragmentDiff($from_segment, $to_segment, $delimiters) as $fragment_edit) { // increase granularity - if ( $fragment_edit instanceof FineDiffReplaceOp && $has_next_stage ) { + if ($fragment_edit instanceof FineDiffReplaceOp && $has_next_stage) { $this->_processGranularity( substr($this->from_text, $this->from_offset, $fragment_edit->getFromLen()), $fragment_edit->getText() ); } // fuse copy ops whenever possible - else if ( $fragment_edit instanceof FineDiffCopyOp && $this->last_edit instanceof FineDiffCopyOp ) { - $this->edits[count($this->edits)-1]->increase($fragment_edit->getFromLen()); + elseif ($fragment_edit instanceof FineDiffCopyOp && $this->last_edit instanceof FineDiffCopyOp) { + $this->edits[count($this->edits) - 1]->increase($fragment_edit->getFromLen()); $this->from_offset += $fragment_edit->getFromLen(); - } - else { + } else { /* $fragment_edit instanceof FineDiffCopyOp */ /* $fragment_edit instanceof FineDiffDeleteOp */ /* $fragment_edit instanceof FineDiffInsertOp */ @@ -476,7 +540,7 @@ private function _processGranularity($from_segment, $to_segment) { $this->from_offset += $fragment_edit->getFromLen(); } } - $this->stackpointer--; + --$this->stackpointer; } /** @@ -486,15 +550,16 @@ private function _processGranularity($from_segment, $to_segment) { * This function is naturally recursive, however for performance purpose * a local job queue is used instead of outright recursivity. */ - private static function doFragmentDiff($from_text, $to_text, $delimiters) { + private static function doFragmentDiff($from_text, $to_text, $delimiters) + { // Empty delimiter means character-level diffing. // In such case, use code path optimized for character-level // diffing. - if ( empty($delimiters) ) { + if (empty($delimiters)) { return FineDiff::doCharDiff($from_text, $to_text); } - $result = array(); + $result = []; // fragment-level diffing $from_text_len = strlen($from_text); @@ -502,23 +567,21 @@ private static function doFragmentDiff($from_text, $to_text, $delimiters) { $from_fragments = FineDiff::extractFragments($from_text, $delimiters); $to_fragments = FineDiff::extractFragments($to_text, $delimiters); - $jobs = array(array(0, $from_text_len, 0, $to_text_len)); - - $cached_array_keys = array(); + $jobs = [[0, $from_text_len, 0, $to_text_len]]; - while ( $job = array_pop($jobs) ) { + $cached_array_keys = []; + while ($job = array_pop($jobs)) { // get the segments which must be diff'ed - list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + [$from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end] = $job; // catch easy cases first $from_segment_length = $from_segment_end - $from_segment_start; $to_segment_length = $to_segment_end - $to_segment_start; - if ( !$from_segment_length || !$to_segment_length ) { - if ( $from_segment_length ) { + if (!$from_segment_length || !$to_segment_length) { + if ($from_segment_length) { $result[$from_segment_start * 4] = new FineDiffDeleteOp($from_segment_length); - } - else if ( $to_segment_length ) { + } elseif ($to_segment_length) { $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_length)); } continue; @@ -529,56 +592,57 @@ private static function doFragmentDiff($from_text, $to_text, $delimiters) { $from_base_fragment_index = $from_segment_start; - $cached_array_keys_for_current_segment = array(); + $cached_array_keys_for_current_segment = []; - while ( $from_base_fragment_index < $from_segment_end ) { + while ($from_base_fragment_index < $from_segment_end) { $from_base_fragment = $from_fragments[$from_base_fragment_index]; $from_base_fragment_length = strlen($from_base_fragment); // performance boost: cache array keys - if ( !isset($cached_array_keys_for_current_segment[$from_base_fragment]) ) { - if ( !isset($cached_array_keys[$from_base_fragment]) ) { + if (!isset($cached_array_keys_for_current_segment[$from_base_fragment])) { + if (!isset($cached_array_keys[$from_base_fragment])) { $to_all_fragment_indices = $cached_array_keys[$from_base_fragment] = array_keys($to_fragments, $from_base_fragment, true); - } - else { + } else { $to_all_fragment_indices = $cached_array_keys[$from_base_fragment]; } // get only indices which falls within current segment - if ( $to_segment_start > 0 || $to_segment_end < $to_text_len ) { - $to_fragment_indices = array(); - foreach ( $to_all_fragment_indices as $to_fragment_index ) { - if ( $to_fragment_index < $to_segment_start ) { continue; } - if ( $to_fragment_index >= $to_segment_end ) { break; } + if ($to_segment_start > 0 || $to_segment_end < $to_text_len) { + $to_fragment_indices = []; + foreach ($to_all_fragment_indices as $to_fragment_index) { + if ($to_fragment_index < $to_segment_start) { + continue; + } + if ($to_fragment_index >= $to_segment_end) { + break; + } $to_fragment_indices[] = $to_fragment_index; } $cached_array_keys_for_current_segment[$from_base_fragment] = $to_fragment_indices; - } - else { + } else { $to_fragment_indices = $to_all_fragment_indices; } - } - else { + } else { $to_fragment_indices = $cached_array_keys_for_current_segment[$from_base_fragment]; } // iterate through collected indices - foreach ( $to_fragment_indices as $to_base_fragment_index ) { + foreach ($to_fragment_indices as $to_base_fragment_index) { $fragment_index_offset = $from_base_fragment_length; // iterate until no more match - for (;;) { + while (true){ $fragment_from_index = $from_base_fragment_index + $fragment_index_offset; - if ( $fragment_from_index >= $from_segment_end ) { + if ($fragment_from_index >= $from_segment_end) { break; } $fragment_to_index = $to_base_fragment_index + $fragment_index_offset; - if ( $fragment_to_index >= $to_segment_end ) { + if ($fragment_to_index >= $to_segment_end) { break; } - if ( $from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index] ) { + if ($from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index]) { break; } $fragment_length = strlen($from_fragments[$fragment_from_index]); $fragment_index_offset += $fragment_length; } - if ( $fragment_index_offset > $best_copy_length ) { + if ($fragment_index_offset > $best_copy_length) { $best_copy_length = $fragment_index_offset; $best_from_start = $from_base_fragment_index; $best_to_start = $to_base_fragment_index; @@ -587,27 +651,27 @@ private static function doFragmentDiff($from_text, $to_text, $delimiters) { $from_base_fragment_index += strlen($from_base_fragment); // If match is larger than half segment size, no point trying to find better // TODO: Really? - if ( $best_copy_length >= $from_segment_length / 2) { + if ($best_copy_length >= $from_segment_length / 2) { break; } // no point to keep looking if what is left is less than // current best match - if ( $from_base_fragment_index + $best_copy_length >= $from_segment_end ) { + if ($from_base_fragment_index + $best_copy_length >= $from_segment_end) { break; } } - if ( $best_copy_length ) { - $jobs[] = array($from_segment_start, $best_from_start, $to_segment_start, $best_to_start); + if ($best_copy_length) { + $jobs[] = [$from_segment_start, $best_from_start, $to_segment_start, $best_to_start]; $result[$best_from_start * 4 + 2] = new FineDiffCopyOp($best_copy_length); - $jobs[] = array($best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end); - } - else { - $result[$from_segment_start * 4 ] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length)); + $jobs[] = [$best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end]; + } else { + $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length)); } } ksort($result, SORT_NUMERIC); + return array_values($result); } @@ -627,62 +691,61 @@ private static function doFragmentDiff($from_text, $to_text, $delimiters) { * performant. For word-sized strings, doCharDiff() is somewhat more * performant. */ - private static function doCharDiff($from_text, $to_text) { - $result = array(); - $jobs = array(array(0, strlen($from_text), 0, strlen($to_text))); - while ( $job = array_pop($jobs) ) { + private static function doCharDiff($from_text, $to_text) + { + $result = []; + $jobs = [[0, strlen($from_text), 0, strlen($to_text)]]; + while ($job = array_pop($jobs)) { // get the segments which must be diff'ed - list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + [$from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end] = $job; $from_segment_len = $from_segment_end - $from_segment_start; $to_segment_len = $to_segment_end - $to_segment_start; // catch easy cases first - if ( !$from_segment_len || !$to_segment_len ) { - if ( $from_segment_len ) { + if (!$from_segment_len || !$to_segment_len) { + if ($from_segment_len) { $result[$from_segment_start * 4 + 0] = new FineDiffDeleteOp($from_segment_len); - } - else if ( $to_segment_len ) { + } elseif ($to_segment_len) { $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_len)); } continue; } - if ( $from_segment_len >= $to_segment_len ) { + if ($from_segment_len >= $to_segment_len) { $copy_len = $to_segment_len; - while ( $copy_len ) { + while ($copy_len) { $to_copy_start = $to_segment_start; $to_copy_start_max = $to_segment_end - $copy_len; - while ( $to_copy_start <= $to_copy_start_max ) { + while ($to_copy_start <= $to_copy_start_max) { $from_copy_start = strpos(substr($from_text, $from_segment_start, $from_segment_len), substr($to_text, $to_copy_start, $copy_len)); - if ( $from_copy_start !== false ) { + if ($from_copy_start !== false) { $from_copy_start += $from_segment_start; break 2; } - $to_copy_start++; + ++$to_copy_start; } - $copy_len--; + --$copy_len; } - } - else { + } else { $copy_len = $from_segment_len; - while ( $copy_len ) { + while ($copy_len) { $from_copy_start = $from_segment_start; $from_copy_start_max = $from_segment_end - $copy_len; - while ( $from_copy_start <= $from_copy_start_max ) { + while ($from_copy_start <= $from_copy_start_max) { $to_copy_start = strpos(substr($to_text, $to_segment_start, $to_segment_len), substr($from_text, $from_copy_start, $copy_len)); - if ( $to_copy_start !== false ) { + if ($to_copy_start !== false) { $to_copy_start += $to_segment_start; break 2; } - $from_copy_start++; + ++$from_copy_start; } - $copy_len--; + --$copy_len; } } // match found - if ( $copy_len ) { - $jobs[] = array($from_segment_start, $from_copy_start, $to_segment_start, $to_copy_start); + if ($copy_len) { + $jobs[] = [$from_segment_start, $from_copy_start, $to_segment_start, $to_copy_start]; $result[$from_copy_start * 4 + 2] = new FineDiffCopyOp($copy_len); - $jobs[] = array($from_copy_start + $copy_len, $from_segment_end, $to_copy_start + $copy_len, $to_segment_end); + $jobs[] = [$from_copy_start + $copy_len, $from_segment_end, $to_copy_start + $copy_len, $to_segment_end]; } // no match, so delete all, insert all else { @@ -690,6 +753,7 @@ private static function doCharDiff($from_text, $to_text) { } } ksort($result, SORT_NUMERIC); + return array_values($result); } @@ -703,49 +767,52 @@ private static function doCharDiff($from_text, $to_text) { * Careful: No check is performed as to the validity of the * delimiters. */ - private static function extractFragments($text, $delimiters) { + private static function extractFragments($text, $delimiters) + { // special case: split into characters - if ( empty($delimiters) ) { + if (empty($delimiters)) { $chars = str_split($text, 1); $chars[strlen($text)] = ''; + return $chars; } - $fragments = array(); + $fragments = []; $start = $end = 0; - for (;;) { + while (true){ $end += strcspn($text, $delimiters, $end); $end += strspn($text, $delimiters, $end); - if ( $end === $start ) { + if ($end === $start) { break; } $fragments[$start] = substr($text, $start, $end - $start); $start = $end; } $fragments[$start] = ''; + return $fragments; } /** - * Stock opcode renderers + * Stock opcode renderers. */ - private static function renderToTextFromOpcode($opcode, $from, $from_offset, $from_len) { - if ( $opcode === 'c' || $opcode === 'i' ) { + private static function renderToTextFromOpcode($opcode, $from, $from_offset, $from_len) + { + if ($opcode === 'c' || $opcode === 'i') { echo substr($from, $from_offset, $from_len); } } - private static function renderDiffToHTMLFromOpcode($opcode, $from, $from_offset, $from_len) { - if ( $opcode === 'c' ) { + private static function renderDiffToHTMLFromOpcode($opcode, $from, $from_offset, $from_len) + { + if ($opcode === 'c') { echo htmlspecialchars(substr($from, $from_offset, $from_len)); - } - else if ( $opcode === 'd' ) { + } elseif ($opcode === 'd') { $deletion = substr($from, $from_offset, $from_len); - if ( strcspn($deletion, " \n\r") === 0 ) { - $deletion = str_replace(array("\n","\r"), array('\n','\r'), $deletion); + if (strcspn($deletion, " \n\r") === 0) { + $deletion = str_replace(["\n", "\r"], ['\n', '\r'], $deletion); } echo '', htmlspecialchars($deletion), ''; - } - else /* if ( $opcode === 'i' ) */ { + } else { /* if ( $opcode === 'i' ) */ echo '', htmlspecialchars(substr($from, $from_offset, $from_len)), ''; } } diff --git a/appinfo/app.php b/appinfo/app.php index d0326b8..f3413d0 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -1,6 +1,8 @@ =7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^7 | ^8 | ^9", + "psalm/phar": "^3.11@dev", + "react/promise": "^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "https://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.6.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2022-02-20T17:52:18+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.8.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", + "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.4", + "friendsofphp/php-cs-fixer": "^2.3", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6 || ^7 || ^8", + "psalm/phar": "^3.11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Amp\\ByteStream\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2021-03-30T17:13:30+00:00" + }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.5", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-17T14:14:24+00:00" + }, + { + "name": "composer/pcre", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T20:21:48+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.13.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2", + "vimeo/psalm": "^4.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.3" + }, + "time": "2022-07-02T10:48:51+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-02-28T11:07:21+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.2", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" + }, + "time": "2022-03-02T22:36:06+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.12.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "eae11d945e2885d86e1c080eec1bb30a2aa27998" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/eae11d945e2885d86e1c080eec1bb30a2aa27998", + "reference": "eae11d945e2885d86e1c080eec1bb30a2aa27998", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.13", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php80": "^1.25", + "symfony/polyfill-php81": "^1.25", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^1.5", + "mikey179/vfsstream": "^1.6.10", + "php-coveralls/php-coveralls": "^2.5.2", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.15", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.0", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.12.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2022-10-12T14:20:51+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" + }, + "time": "2020-12-01T19:48:11+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + }, + "time": "2022-09-04T07:30:47+00:00" + }, + { + "name": "openlss/lib-array2xml", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nullivex/lib-array2xml.git", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "LSS": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bryan Tong", + "email": "bryan@nullivex.com", + "homepage": "https://www.nullivex.com" + }, + { + "name": "Tony Butler", + "email": "spudz76@gmail.com", + "homepage": "https://www.nullivex.com" + } + ], + "description": "Array2XML conversion library credit to lalit.org", + "homepage": "https://www.nullivex.com", + "keywords": [ + "array", + "array conversion", + "xml", + "xml conversion" + ], + "support": { + "issues": "https://github.com/nullivex/lib-array2xml/issues", + "source": "https://github.com/nullivex/lib-array2xml/tree/master" + }, + "time": "2019-03-29T20:06:56+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + }, + "time": "2022-10-14T12:47:21+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.8.10", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "0c4459dc42c568b818b3f25186589f3acddc1823" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0c4459dc42c568b818b3f25186589f3acddc1823", + "reference": "0c4459dc42c568b818b3f25186589f3acddc1823", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.8.10" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-10-17T14:23:35+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "symfony/console", + "version": "v5.4.14", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/984ea2c0f45f42dfed01d2f3987b187467c4b16d", + "reference": "984ea2c0f45f42dfed01d2f3987b187467c4b16d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "psr/log": ">=3", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, + "require-dev": { + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.14" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-07T08:01:20+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-05T16:45:39+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.13" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-21T19:53:16+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-29T07:37:50+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.4.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-20T13:00:38+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "433d05519ce6990bf3530fba6957499d327395c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-10T07:21:04+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/process", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.4.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T16:58:25+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-30T19:17:29+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v5.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6df7a3effde34d81717bbef4591e5ffe32226d69", + "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.4.13" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-28T13:19:49+00:00" + }, + { + "name": "symfony/string", + "version": "v5.4.14", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "089e7237497fae7a9c404d0c3aeb8db3254733e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/089e7237497fae7a9c404d0c3aeb8db3254733e4", + "reference": "089e7237497fae7a9c404d0c3aeb8db3254733e4", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.4.14" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-05T15:16:54+00:00" + }, + { + "name": "vimeo/psalm", + "version": "4.29.0", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3", + "reference": "7ec5ffbd5f68ae03782d7fd33fff0c45a69f95b3", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.4.2", + "amphp/byte-stream": "^1.5", + "composer/package-versions-deprecated": "^1.8.0", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.3", + "felixfbecker/language-server-protocol": "^1.5", + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "nikic/php-parser": "^4.13", + "openlss/lib-array2xml": "^1.0", + "php": "^7.1|^8", + "sebastian/diff": "^3.0 || ^4.0", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", + "symfony/polyfill-php80": "^1.25", + "webmozart/path-util": "^2.3" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "brianium/paratest": "^4.0||^6.0", + "ext-curl": "*", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpdocumentor/reflection-docblock": "^5", + "phpmyadmin/sql-parser": "5.1.0||dev-master", + "phpspec/prophecy": ">=1.9.0", + "phpstan/phpdoc-parser": "1.2.* || 1.6.4", + "phpunit/phpunit": "^9.0", + "psalm/plugin-phpunit": "^0.16", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^4.3 || ^5.0 || ^6.0", + "weirdan/prophecy-shim": "^1.0 || ^2.0" + }, + "suggest": { + "ext-curl": "In order to send data to shepherd", + "ext-igbinary": "^2.0.5 is required, used to serialize caching data" + }, + "bin": [ + "psalm", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor", + "psalter" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev", + "dev-3.x": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php", + "src/spl_object_id.php" + ], + "psr-4": { + "Psalm\\": "src/Psalm/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php" + ], + "support": { + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm/tree/4.29.0" + }, + "time": "2022-10-11T17:09:17+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, + "abandoned": "symfony/filesystem", + "time": "2015-12-17T08:42:14+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/controller/noteapicontroller.php b/controller/noteapicontroller.php index 148eb3b..b64bfd1 100644 --- a/controller/noteapicontroller.php +++ b/controller/noteapicontroller.php @@ -1,6 +1,8 @@ user = $userId ? $userId : $_SERVER['PHP_AUTH_USER']; @@ -39,39 +40,41 @@ public function __construct($AppName, } /** - * Gets all versions of a note + * Gets all versions of a note. * * @NoAdminRequired + * * @NoCSRFRequired + * * @CORS * * @return array + * * @throws \OCP\Lock\LockedException * @throws \OC\User\NoUserException */ - public function getAllVersions() { - $source = $this->request->getParam( "file_name", "" ); - $errorMessages = array(); + public function getAllVersions() + { + $source = $this->request->getParam('file_name', ''); + $errorMessages = []; try { - list ($uid, $filename) = Storage::getUidAndFilename($source); + [$uid, $filename] = Storage::getUidAndFilename($source); $versions = Storage::getVersions($uid, $filename, $source); - $versionsResults = array(); + $versionsResults = []; - if (is_array( $versions ) && (count($versions) > 0)) - { - require_once __DIR__ . '/../3rdparty/finediff/finediff.php'; + if (is_array($versions) && (count($versions) > 0)) { + require_once __DIR__.'/../3rdparty/finediff/finediff.php'; $users_view = new View('/'.$uid); - $currentData = $users_view->file_get_contents('files/' . $filename); + $currentData = $users_view->file_get_contents('files/'.$filename); - foreach ($versions as $versionData) - { + foreach ($versions as $versionData) { // get timestamp of version - $mtime = (int)$versionData["version"]; + $mtime = (int) $versionData['version']; // get filename of note version - $versionFileName = 'files_versions/' . $filename . '.v' . $mtime; + $versionFileName = 'files_versions/'.$filename.'.v'.$mtime; // load the data from the file $data = $users_view->file_get_contents($versionFileName); @@ -80,128 +83,130 @@ public function getAllVersions() { $opcodes = \FineDiff::getDiffOpcodes($currentData, $data); $html = \FineDiff::renderDiffToHTMLFromOpcodes($currentData, $opcodes); - $versionsResults[] = array( - "timestamp" => $mtime, - "humanReadableTimestamp" => $versionData["humanReadableTimestamp"], - "diffHtml" => $html, - "data" => $data, - ); + $versionsResults[] = [ + 'timestamp' => $mtime, + 'humanReadableTimestamp' => $versionData['humanReadableTimestamp'], + 'diffHtml' => $html, + 'data' => $data, + ]; } } } catch (\OCP\Files\NotFoundException $exception) { // Requested file was not found, silently fail (for now) - $versionsResults = array(); + $versionsResults = []; - $errorMessages[] = "Requested file was not found!"; + $errorMessages[] = 'Requested file was not found!'; } - return array( - "file_name" => $source, - "versions" => $versionsResults, - "error_messages" => $errorMessages - ); + return [ + 'file_name' => $source, + 'versions' => $versionsResults, + 'error_messages' => $errorMessages, + ]; } /** - * Returns information about the ownCloud server + * Returns information about the ownCloud server. * * @NoAdminRequired + * * @NoCSRFRequired + * * @CORS * * @return string|array + * * @throws Exception */ - public function getAppInfo() { + public function getAppInfo() + { $appManager = \OC::$server->getAppManager(); $versionsAppEnabled = $appManager->isEnabledForUser('files_versions'); $trashAppEnabled = $appManager->isEnabledForUser('files_trashbin'); $notesPathExists = false; - $notesPath = $this->request->getParam( "notes_path", "" ); + $notesPath = $this->request->getParam('notes_path', ''); // check if notes path exists - if ($notesPath !== "") - { - $notesPath = "/files" . (string)$notesPath; - $view = new \OC\Files\View('/' . $this->user); + if ($notesPath !== '') { + $notesPath = '/files'.(string) $notesPath; + $view = new \OC\Files\View('/'.$this->user); $notesPathExists = $view->is_dir($notesPath); } return [ - "user" => $this->user, - "versions_app" => $versionsAppEnabled, - "trash_app" => $trashAppEnabled, - "versioning" => true, - "app_version" => \OC::$server->getConfig()->getAppValue('qownnotesapi', 'installed_version'), - "server_version" => \OC::$server->getSystemConfig()->getValue('version'), - "notes_path_exists" => $notesPathExists, + 'user' => $this->user, + 'versions_app' => $versionsAppEnabled, + 'trash_app' => $trashAppEnabled, + 'versioning' => true, + 'app_version' => \OC::$server->getConfig()->getAppValue('qownnotesapi', 'installed_version'), + 'server_version' => \OC::$server->getSystemConfig()->getValue('version'), + 'notes_path_exists' => $notesPathExists, ]; } /** - * Gets information about trashed notes + * Gets information about trashed notes. * * @NoAdminRequired + * * @NoCSRFRequired + * * @CORS * * @return string|array + * * @throws \OCP\Lock\LockedException */ - public function getTrashedNotes() { - $dir = $this->request->getParam( "dir", "" ); - $customFileExtensions = $this->request->getParam( "extensions", array() ); + public function getTrashedNotes() + { + $dir = $this->request->getParam('dir', ''); + $customFileExtensions = $this->request->getParam('extensions', []); if (!is_array($customFileExtensions)) { - $customFileExtensions = array(); + $customFileExtensions = []; } - $noteFileExtensions = array_merge( array("md", "txt"), $customFileExtensions); + $noteFileExtensions = array_merge(['md', 'txt'], $customFileExtensions); // remove leading "/" - if ( substr( $dir, 0, 1 ) === "/" ) - { - $dir = substr( $dir, 1 ); + if (substr($dir, 0, 1) === '/') { + $dir = substr($dir, 1); } // remove trailing "/" - if ( substr( $dir, -1 ) === "/" ) - { - $dir = substr( $dir, 0, -1 ); + if (substr($dir, -1) === '/') { + $dir = substr($dir, 0, -1); } - $sortAttribute = $this->request->getParam( "sort", "mtime" ); - $sortDirectionParam = $this->request->getParam( "sortdirection", "" ); - $sortDirection = ( $sortDirectionParam !== "" ) ? ( $sortDirectionParam === 'desc' ) : true; - $filesInfo = array(); + $sortAttribute = $this->request->getParam('sort', 'mtime'); + $sortDirectionParam = $this->request->getParam('sortdirection', ''); + $sortDirection = ($sortDirectionParam !== '') ? ($sortDirectionParam === 'desc') : true; + $filesInfo = []; // generate the file list try { - $files = Helper::getTrashFiles("/", $this->user, $sortAttribute, $sortDirection); + $files = Helper::getTrashFiles('/', $this->user, $sortAttribute, $sortDirection); $filesInfo = Helper::formatFileInfos($files); } catch (Exception $e) { - } // only return notes (with extension ".txt", ".md" and the custom extensions) in the $dir directory - $resultFilesInfo = array(); - foreach($filesInfo as $fileInfo) - { - $pathParts = pathinfo($fileInfo["name"]); - $extension = isset($pathParts["extension"]) ? $pathParts["extension"] : ""; + $resultFilesInfo = []; + foreach ($filesInfo as $fileInfo) { + $pathParts = pathinfo($fileInfo['name']); + $extension = $pathParts['extension'] ?? ''; // if $fileInfo["extraData"] is not set we will have to show the note files from all folders in QOwnNotes - $isInDir = isset($fileInfo["extraData"]) ? - (strpos($fileInfo["extraData"], $dir . "/" . $fileInfo["name"]) === 0) : true; - $isNoteFile = in_array($extension, $noteFileExtensions); + $isInDir = isset($fileInfo['extraData']) ? + (strpos($fileInfo['extraData'], $dir.'/'.$fileInfo['name']) === 0) : true; + $isNoteFile = in_array($extension, $noteFileExtensions, true); - if ($isInDir && $isNoteFile) - { - $timestamp = (int) ($fileInfo["mtime"] / 1000); - $fileName = '/files_trashbin/files/' . $fileInfo["name"] . ".d$timestamp"; + if ($isInDir && $isNoteFile) { + $timestamp = (int) ($fileInfo['mtime'] / 1000); + $fileName = '/files_trashbin/files/'.$fileInfo['name'].".d$timestamp"; - $view = new \OC\Files\View('/' . $this->user); - $data = ""; + $view = new \OC\Files\View('/'.$this->user); + $data = ''; // load the file data $handle = $view->fopen($fileName, 'rb'); @@ -212,19 +217,19 @@ public function getTrashedNotes() { } } - $dateString = isset($fileInfo["date"]) ? $fileInfo["date"] : date("Y-m-d H:i:s", $timestamp); + $dateString = $fileInfo['date'] ?? date('Y-m-d H:i:s', $timestamp); $resultFilesInfo[] = [ - "noteName" => $pathParts["filename"], - "fileName" => $fileInfo["name"], - "timestamp" => $timestamp, - "dateString" => $dateString, - "data" => $data, + 'noteName' => $pathParts['filename'], + 'fileName' => $fileInfo['name'], + 'timestamp' => $timestamp, + 'dateString' => $dateString, + 'data' => $data, ]; } } - $data = array(); + $data = []; $data['directory'] = $dir; $data['notes'] = $resultFilesInfo; @@ -232,32 +237,37 @@ public function getTrashedNotes() { } /** - * Restores a trashed note + * Restores a trashed note. * * We try to mimic undelete.php to get all versions restored too. + * * @return string|array + * * @throws \OCP\Files\NotPermittedException + * * @see owncloud/core/apps/files_trashbin/ajax/undelete.php * * @NoAdminRequired + * * @NoCSRFRequired - * @CORS * + * @CORS */ - public function restoreTrashedNote() { - $filename = $this->request->getParam( "file_name" ); - $timestamp = (int) $this->request->getParam( "timestamp" ); + public function restoreTrashedNote() + { + $filename = $this->request->getParam('file_name'); + $timestamp = (int) $this->request->getParam('timestamp'); - $path = $filename . ".d$timestamp"; - $pathParts = pathinfo( $path ); - $path = "//" . $pathParts['basename']; + $path = $filename.".d$timestamp"; + $pathParts = pathinfo($path); + $path = '//'.$pathParts['basename']; - $pathParts = pathinfo( $filename ); + $pathParts = pathinfo($filename); $filename = $pathParts['basename']; $restoreResult = Trashbin::restore($path, $filename, $timestamp); - $data = array(); + $data = []; $data['result'] = $restoreResult; $data['path'] = $path; $data['filename'] = $filename; diff --git a/docker/qownnotesapi.config.php b/docker/qownnotesapi.config.php index b3d9bbc..f4165e8 100644 --- a/docker/qownnotesapi.config.php +++ b/docker/qownnotesapi.config.php @@ -1 +1 @@ - array( - 'versioning' => true, - ), - ); - } +class Capabilities implements ICapability +{ + /** + * @return array + */ + public static function getCapabilities() + { + return [ + 'qownnotes' => [ + 'versioning' => true, + ], + ]; + } } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..715d44d --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,16 @@ +#includes: +# - vendor/phpstan/phpstan-phpunit/extension.neon + +parameters: + inferPrivatePropertyTypeFromConstructor: true + level: 3 + paths: + - 3rdparty + - appinfo + - controller + - lib + - tests + excludePaths: + ignoreErrors: + - message: '#.*NodeDefinition::children.*#' + path: ./src/DependencyInjection diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..05eddc6 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/integration/AppTest.php b/tests/integration/AppTest.php index ab8158a..fc602ce 100644 --- a/tests/integration/AppTest.php +++ b/tests/integration/AppTest.php @@ -1,6 +1,8 @@ container = $app->getContainer(); } - public function testAppInstalled() { + public function testAppInstalled() + { $appManager = $this->container->query('OCP\App\IAppManager'); $this->assertTrue($appManager->isInstalled('qownnotesapi')); } diff --git a/tests/unit/controller/NoteApiControllerTest.php b/tests/unit/controller/NoteApiControllerTest.php index f80a6d7..3976d30 100644 --- a/tests/unit/controller/NoteApiControllerTest.php +++ b/tests/unit/controller/NoteApiControllerTest.php @@ -1,6 +1,8 @@ request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - - $user = "admin"; - $this->loginAsUser( $user ); - - $this->controller = new NoteApiController( 'qownnotesapi', $user, $this->request ); - } - - public function testGetAllVersions() { - $fileName = "/Notes/some-not-existing-test-file.txt"; - $this->request->expects( $this->any() ) - ->method( "getParam" ) - ->with( "file_name" ) - ->willReturn( $fileName ); - - $result = $this->controller->getAllVersions(); - - $this->assertArrayHasKey( "file_name", $result ); - $this->assertArrayHasKey( "versions", $result ); - $this->assertEquals( $fileName, $result["file_name"] ); - } - - public function testGetAppInfo() { - $path = "/Notes"; - $this->request->expects( $this->any() ) - ->method( "getParam" ) - ->with( "notes_path" ) - ->willReturn( $path ); - - $result = $this->controller->getAppInfo(); - - $this->assertArrayHasKey( "versions_app", $result ); - $this->assertArrayHasKey( "trash_app", $result ); - $this->assertArrayHasKey( "versioning", $result ); - $this->assertArrayHasKey( "app_version", $result ); - $this->assertArrayHasKey( "server_version", $result ); - $this->assertArrayHasKey( "notes_path_exists", $result ); - $this->assertTrue( $result["versions_app"] ); - $this->assertTrue( $result["trash_app"] ); - $this->assertEquals( $result["app_version"], \OC::$server->getConfig()->getAppValue('qownnotesapi', 'installed_version') ); - } - - public function testGetTrashedNotes() { - $this->request->expects( $this->at(0) ) - ->method( "getParam" ) - ->with( "dir", "" ) - ->willReturn( "/Notes" ); - $this->request->expects( $this->at(1) ) - ->method( "getParam" ) - ->with( "extensions", array() ) - ->willReturn( array() ); - $this->request->expects( $this->at(2) ) - ->method( "getParam" ) - ->with( "sort", "mtime" ) - ->willReturn( "mtime" ); - - $result = $this->controller->getTrashedNotes(); - - $this->assertArrayHasKey( "directory", $result ); - $this->assertArrayHasKey( "notes", $result ); - $this->assertEquals( $result["directory"], "Notes" ); - $this->assertEquals( $result["notes"], array() ); - } - - public function testRestoreTrashedNote() { - $file = "some-not-existing-test-file.txt"; - $timestamp = time(); - - $this->request->expects( $this->at(0) ) - ->method( "getParam" ) - ->with( "file_name" ) - ->willReturn( "/Notes/$file" ); - $this->request->expects( $this->at(1) ) - ->method( "getParam" ) - ->with( "timestamp" ) - ->willReturn( $timestamp ); - - $result = $this->controller->restoreTrashedNote(); - - $this->assertArrayHasKey( "result", $result ); - $this->assertArrayHasKey( "path", $result ); - $this->assertArrayHasKey( "filename", $result ); - $this->assertFalse( $result["result"] ); - $this->assertEquals( $result["path"], "//$file.d$timestamp" ); - $this->assertEquals( $result["filename"], $file ); - } +class NoteApiControllerTest extends TestCase +{ + /** @var NoteApiController */ + private $controller; + + /** @var IRequest */ + private $request; + + public function setUp() + { + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + + $user = 'admin'; + $this->loginAsUser($user); + + $this->controller = new NoteApiController('qownnotesapi', $user, $this->request); + } + + public function testGetAllVersions() + { + $fileName = '/Notes/some-not-existing-test-file.txt'; + $this->request->expects($this->any()) + ->method('getParam') + ->with('file_name') + ->willReturn($fileName); + + $result = $this->controller->getAllVersions(); + + $this->assertArrayHasKey('file_name', $result); + $this->assertArrayHasKey('versions', $result); + $this->assertEquals($fileName, $result['file_name']); + } + + public function testGetAppInfo() + { + $path = '/Notes'; + $this->request->expects($this->any()) + ->method('getParam') + ->with('notes_path') + ->willReturn($path); + + $result = $this->controller->getAppInfo(); + + $this->assertArrayHasKey('versions_app', $result); + $this->assertArrayHasKey('trash_app', $result); + $this->assertArrayHasKey('versioning', $result); + $this->assertArrayHasKey('app_version', $result); + $this->assertArrayHasKey('server_version', $result); + $this->assertArrayHasKey('notes_path_exists', $result); + $this->assertTrue($result['versions_app']); + $this->assertTrue($result['trash_app']); + $this->assertEquals($result['app_version'], \OC::$server->getConfig()->getAppValue('qownnotesapi', 'installed_version')); + } + + public function testGetTrashedNotes() + { + $this->request->expects($this->at(0)) + ->method('getParam') + ->with('dir', '') + ->willReturn('/Notes'); + $this->request->expects($this->at(1)) + ->method('getParam') + ->with('extensions', []) + ->willReturn([]); + $this->request->expects($this->at(2)) + ->method('getParam') + ->with('sort', 'mtime') + ->willReturn('mtime'); + + $result = $this->controller->getTrashedNotes(); + + $this->assertArrayHasKey('directory', $result); + $this->assertArrayHasKey('notes', $result); + $this->assertEquals($result['directory'], 'Notes'); + $this->assertEquals($result['notes'], []); + } + + public function testRestoreTrashedNote() + { + $file = 'some-not-existing-test-file.txt'; + $timestamp = time(); + + $this->request->expects($this->at(0)) + ->method('getParam') + ->with('file_name') + ->willReturn("/Notes/$file"); + $this->request->expects($this->at(1)) + ->method('getParam') + ->with('timestamp') + ->willReturn($timestamp); + + $result = $this->controller->restoreTrashedNote(); + + $this->assertArrayHasKey('result', $result); + $this->assertArrayHasKey('path', $result); + $this->assertArrayHasKey('filename', $result); + $this->assertFalse($result['result']); + $this->assertEquals($result['path'], "//$file.d$timestamp"); + $this->assertEquals($result['filename'], $file); + } }