-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V13 #4
base: master
Are you sure you want to change the base?
V13 #4
Changes from all commits
ed63857
7df963f
0a02f54
fa7b5f7
9ce3ef4
b5e1ffe
db53a09
a1a3f25
8e13fbb
4d8cec2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# EditorConfig is awesome: http://EditorConfig.org | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
# Unix-style newlines with a newline ending every file | ||
[*] | ||
charset = utf-8 | ||
end_of_line = lf | ||
indent_style = space | ||
indent_size = 4 | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
|
||
# TS/JS-Files | ||
[*.{ts,js,vue}] | ||
indent_size = 4 | ||
indent_style = tab | ||
|
||
# JSON-Files | ||
[*.json] | ||
indent_style = tab | ||
|
||
# ReST-Files | ||
[*.rst] | ||
indent_size = 4 | ||
max_line_length = 80 | ||
|
||
# YAML-Files | ||
[*.{yaml,yml}] | ||
indent_size = 2 | ||
|
||
# NEON-Files | ||
[*.neon] | ||
indent_size = 2 | ||
indent_style = tab | ||
|
||
# package.json | ||
[package.json] | ||
indent_size = 2 | ||
|
||
# TypoScript | ||
[*.{typoscript,tsconfig}] | ||
indent_size = 2 | ||
|
||
# XLF-Files | ||
[*.xlf] | ||
indent_style = tab | ||
|
||
# SQL-Files | ||
[*.sql] | ||
indent_style = tab | ||
indent_size = 2 | ||
|
||
# .htaccess | ||
[{_.htaccess,.htaccess}] | ||
indent_style = tab |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/.editorconfig export-ignore | ||
/.gitignore export-ignore | ||
/.gitattributes export-ignore | ||
/.php-cs-fixer.php export-ignore | ||
/.phpstan.neon export-ignore |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
/build/ | ||
/composer.lock | ||
/.php_cs.cache | ||
/public/ | ||
/vendor/ | ||
/public/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
$finder = PhpCsFixer\Finder::create() | ||
->in('Classes') | ||
->in('Configuration'); | ||
|
||
$config = \TYPO3\CodingStandards\CsFixerConfig::create(); | ||
return $config | ||
->setUsingCache(false) | ||
->setFinder($finder); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace B13\Tag\Domain\Repository; | ||
|
||
/* | ||
|
@@ -12,75 +14,70 @@ | |
|
||
use TYPO3\CMS\Core\Database\Connection; | ||
use TYPO3\CMS\Core\Database\ConnectionPool; | ||
use TYPO3\CMS\Core\Utility\GeneralUtility; | ||
|
||
/** | ||
* Abstraction layer to keep all tag DB queries within this PHP class. | ||
*/ | ||
class TagRepository | ||
{ | ||
private string $tableName = 'sys_tag'; | ||
private const TABLE_NAME = 'sys_tag'; | ||
|
||
private ConnectionPool $connectionPool; | ||
|
||
public function __construct(ConnectionPool $connectionPool) | ||
{ | ||
$this->connectionPool = $connectionPool; | ||
} | ||
|
||
public function findRecordsForTagNames(array $tagNames): array | ||
{ | ||
$queryBuilder = $this->getConnection()->createQueryBuilder(); | ||
$queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::TABLE_NAME); | ||
$stmt = $queryBuilder | ||
->select('*') | ||
->from($this->tableName) | ||
->from(self::TABLE_NAME) | ||
->where( | ||
$queryBuilder->expr()->in( | ||
'name', | ||
$queryBuilder->createNamedParameter($tagNames, Connection::PARAM_STR_ARRAY) | ||
) | ||
$queryBuilder->expr()->in('name', $queryBuilder->createNamedParameter($tagNames, Connection::PARAM_STR_ARRAY)) | ||
) | ||
->executeQuery(); | ||
|
||
$mappedItems = []; | ||
while ($row = $stmt->fetchAssociative()) { | ||
$mappedItems[$row['name']] = $row['uid']; | ||
} | ||
|
||
return $mappedItems; | ||
} | ||
|
||
public function add(string $tagName, int $pid = 0) | ||
public function add(string $tagName, int $pid = 0): string | ||
{ | ||
$conn = $this->getConnection(); | ||
$conn->insert($this->tableName, ['name' => $tagName, 'pid' => $pid, 'createdon' => $GLOBALS['EXEC_TIME']]); | ||
$conn = $this->connectionPool->getConnectionForTable(self::TABLE_NAME); | ||
$conn->insert( | ||
self::TABLE_NAME, | ||
[ | ||
'name' => $tagName, | ||
'pid' => $pid, | ||
'createdon' => $GLOBALS['EXEC_TIME'], | ||
] | ||
); | ||
|
||
return $conn->lastInsertId(); | ||
} | ||
|
||
/** | ||
* Simple query for looking for tags that contain the search word. No multi-word / and/or search implemented yet. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments like this aren't bad actually ;) |
||
* | ||
* @param string $searchWord | ||
* @return array | ||
*/ | ||
public function search(string $searchWord): array | ||
{ | ||
$queryBuilder = $this->getConnection()->createQueryBuilder(); | ||
$queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::TABLE_NAME); | ||
$stmt = $queryBuilder | ||
->select('*') | ||
->from($this->tableName) | ||
->from(self::TABLE_NAME) | ||
->where( | ||
$queryBuilder->expr()->like( | ||
'name', | ||
$queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($searchWord) . '%') | ||
) | ||
$queryBuilder->expr()->like('name', $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($searchWord) . '%')) | ||
) | ||
->executeQuery(); | ||
|
||
$items = []; | ||
while ($row = $stmt->fetchAssociative()) { | ||
$items[] = [ | ||
'value' => (int)$row['uid'], | ||
'name' => $row['name'] | ||
'name' => $row['name'], | ||
]; | ||
} | ||
return $items; | ||
} | ||
|
||
private function getConnection(): Connection | ||
{ | ||
return GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->tableName); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace B13\Tag\Form; | ||
|
||
/* | ||
|
@@ -13,17 +15,19 @@ | |
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement; | ||
use TYPO3\CMS\Backend\Routing\UriBuilder; | ||
use TYPO3\CMS\Backend\Utility\BackendUtility; | ||
use TYPO3\CMS\Core\Information\Typo3Version; | ||
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction; | ||
use TYPO3\CMS\Core\Utility\GeneralUtility; | ||
use TYPO3\CMS\Core\Utility\StringUtility; | ||
|
||
/** | ||
* Render a list of tags. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments like this aren't bad actually ;) |
||
*/ | ||
class TagListElement extends AbstractFormElement | ||
{ | ||
public function render() | ||
private UriBuilder $uriBuilder; | ||
|
||
public function __construct(UriBuilder $uriBuilder) | ||
{ | ||
$this->uriBuilder = $uriBuilder; | ||
} | ||
|
||
public function render(): array | ||
{ | ||
$resultArray = $this->initializeResultArray(); | ||
$selectedItems = $this->data['parameterArray']['itemFormElValue'] ?? []; | ||
|
@@ -86,36 +90,11 @@ public function render() | |
]; | ||
} | ||
|
||
$ajaxUrl = GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute('ajax_tag_suggest_tags'); | ||
$ajaxUrl = $this->uriBuilder->buildUriFromRoute('ajax_tag_suggest_tags'); | ||
$resultArray['html'] = implode(LF, $html); | ||
|
||
$resultArray['stylesheetFiles'][] = 'EXT:tag/Resources/Public/StyleSheets/tagsinput.css'; | ||
if ((new Typo3Version())->getMajorVersion() < 12) { | ||
$resultArray['requireJsModules'][] = [ | ||
'TYPO3/CMS/Tag/TagsInputElement' => 'function(TagsInputElement) { | ||
new TagsInputElement("' . $tagsId . '", { | ||
itemValue: function(item) { | ||
return item.value || item; | ||
}, | ||
itemText: function(item) { | ||
return item.name || item; | ||
}, | ||
items: ' . json_encode($items) . ', | ||
typeahead: { | ||
minLength: 2, | ||
source: function(query) { | ||
var url = ' . GeneralUtility::quoteJSvalue($ajaxUrl) . ' + "&q=" + query; | ||
return $.getJSON(url); | ||
} | ||
} | ||
}); | ||
}' | ||
]; | ||
} else { | ||
$resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create( | ||
'@b13/tag/tags-input-element.js', | ||
)->instance($tagsId, $items, (string)$ajaxUrl); | ||
} | ||
$resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@b13/tag/tags-input-element.js')->instance($tagsId, $items, (string)$ajaxUrl); | ||
|
||
return $resultArray; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace B13\Tag\Persistence; | ||
|
||
/* | ||
|
@@ -10,33 +12,22 @@ | |
* of the License, or any later version. | ||
*/ | ||
|
||
|
||
use B13\Tag\Domain\Repository\TagRepository; | ||
use B13\Tag\TcaHelper; | ||
use TYPO3\CMS\Backend\Utility\BackendUtility; | ||
use TYPO3\CMS\Core\DataHandling\DataHandler; | ||
use TYPO3\CMS\Core\Utility\GeneralUtility; | ||
use TYPO3\CMS\Core\Utility\MathUtility; | ||
|
||
class PrepareTagItems | ||
{ | ||
protected TagRepository $tagRepository; | ||
|
||
public function __construct() | ||
public function __construct(TagRepository $tagRepository) | ||
{ | ||
$this->tagRepository = GeneralUtility::makeInstance(TagRepository::class); | ||
$this->tagRepository = $tagRepository; | ||
} | ||
|
||
/** | ||
* DataHandler hook to create tags automatically if they don't exist yet. This way, a clean list of | ||
* IDs is entered to DataHandler. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments like this aren't bad actually ;) |
||
* | ||
* @param $incomingFieldArray | ||
* @param $table | ||
* @param $id | ||
* @param DataHandler $dataHandler | ||
*/ | ||
public function processDatamap_preProcessFieldArray(&$incomingFieldArray, $table, $id, DataHandler $dataHandler) | ||
public function processDatamap_preProcessFieldArray(array &$incomingFieldArray, string $table, string $id, DataHandler $dataHandler) | ||
{ | ||
$relevantFields = (new TcaHelper())->findTagFieldsForTable($table); | ||
if (empty($relevantFields)) { | ||
|
@@ -75,13 +66,6 @@ public function processDatamap_preProcessFieldArray(&$incomingFieldArray, $table | |
} | ||
} | ||
|
||
/** | ||
* See what tags are already in the database and add missing tags, and map the tag names to the IDs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments like this aren't bad actually ;) |
||
* | ||
* @param array $tags | ||
* @param int $pid | ||
* @return array | ||
*/ | ||
protected function normalizeValuesAndMapToIds(array $tags, int $pid): array | ||
{ | ||
$unmappedTags = $tags; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments like this aren't bad actually ;)