Skip to content
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

Yform-Integration erweitert #113

Merged
merged 5 commits into from
Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion functions/cache_markitup_profiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ function markitup_cache_defineButtons($type, $profileButtons, $languageSet) {
'name' => 'profiles_buttons_yform_option_'.$table,
'replaceWith' => [ $type => 'function(h) {return btn'.ucfirst($type).'YformCallback(h,"'.rex::getTable($table).'");}']
];
if( !rex_i18n::hasMsg('markitup_'.$data[$table]['name']) ) rex_i18n::addMsg('markitup_'.$data[$table]['name'],$table);
}
if( !rex_i18n::hasMsg('markitup_'.$data[$table]['name']) ) rex_i18n::addMsg('markitup_'.$data[$table]['name'],$table);
$markItUpButtons[$profileButton]['children'] = $data;
} else {
foreach ($parameters as $parameter) {
Expand Down
66 changes: 47 additions & 19 deletions lib/class.markitup.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ class markitup

static $yform_callback = null;

static $type_in_scope = [
'varchar' => 'Type LIKE \'varchar%\'',
'text' => 'Type = \'text\'',
'mediumtext' => 'Type = \'mediumtext\'',
];

public static function insertProfile($name, $description = '', $type = '', $minheight = '300', $maxheight = '800', $urltype = 'relative', $markitupButtons = '')
{
$sql = rex_sql::factory();
Expand Down Expand Up @@ -168,7 +174,7 @@ public static function yformLinkInUse( $table_name, $data_id, $tableset=null, $f
elseif( 2 === $tableset || 3 == $tableset )
{
try {
$tableset = $sql->getArray('SELECT id, table_name FROM rex_yform_fields',[],PDO::FETCH_KEY_PAIR);
$tableset = $sql->getArray('SELECT id, table_name FROM rex_yform_table',[],PDO::FETCH_KEY_PAIR);
} catch (\Exception $e) {
$tableset = []; // insb. falls es rex_yform_fields nicht gibt ($tableset = [frei angegeben])
}
Expand All @@ -186,29 +192,28 @@ public static function yformLinkInUse( $table_name, $data_id, $tableset=null, $f
// Wenn $fullResult angefordert ist, werden alle Tabellen durchlaufen und je Tabelle mit
// gefundenem Link die Satznummern zurückgemeldet.
// Ansonsten wird beim ersten Fund beendet
$limit = true !== $fullResult ? 'LIMIT 1' : '';
$result = [];
$limit = ' LIMIT 1';
if( true == $fullResult )
{
$limit = '';
}
elseif( is_numeric($fullResult) )
{
$limit = ' LIMIT '.$fullResult;
$fullResult = true;
}
else {
$fullResult = false;
}

$result = [];
foreach( $tableset as $table ){

// Alle Felder ermitteln, deren Typen mit varchar(xx) oder text sind.
try {
$qry = 'SHOW FIELDS FROM '.$sql->escapeIdentifier($table).' WHERE Type LIKE \'varchar%\' OR Type = \'text\'';
$fields = array_column( $sql->getArray( $qry ), 'Field');
if( !$fields ) continue;
} catch (\Exception $e) {
continue; // Falls es die Tabelle nicht gibt; relevant für
}

// Je Feld die Abfrage aufbauen, ob der Link dort vorkommt.
foreach( $fields as &$field )
{
$field = 'LOCATE(\'yform:'.$table_name.'/'.$data_id.'\','.$sql->escapeIdentifier($field).')';
}
$qry = 'SELECT id FROM '.$sql->escapeIdentifier($table).' WHERE '.implode(' OR ',$fields ).$limit;
$where = self::yformInUseWhere ( $table, $table_name, $data_id );
$qry = 'SELECT id FROM '.$sql->escapeIdentifier($table).' WHERE '.$where.$limit;
if( $inUse = $sql->getArray( $qry ) )
{
if( $limit ) return true;
if( !$fullResult ) return true;
$result[$table] = array_column( $inUse, 'id' );
}
}
Expand All @@ -217,4 +222,27 @@ public static function yformLinkInUse( $table_name, $data_id, $tableset=null, $f
return false;
}

static function yformInUseWhere ( $target_table, $locator_table, $locator_id, $fields_in_scope=null, $type_in_scope=null ){
// Alle Felder ermitteln, deren Typen mit varchar(xx), text etc. sind.
$sql = rex_sql::factory();
try {
$condition = [];
if( null === $type_in_scope ) $type_in_scope = self::$type_in_scope;
if( is_array($type_in_scope) ) $condition[] = implode(' OR ',$type_in_scope);
if( is_array($fields_in_scope) ) $condition[] = 'Field IN (\''.implode('\',\'',$fields_in_scope).'\')';
if( !$condition ) return '';
$qry = 'SHOW FIELDS FROM '.$sql->escapeIdentifier($target_table).' WHERE (' . implode(') AND (',$condition) .')';
$fields = array_column( $sql->getArray( $qry ), 'Field');
} catch (\Exception $e) {
return ''; // Falls es die Tabelle nicht gibt;
}

// Je Feld die Abfrage aufbauen, ob der Link dort vorkommt.
foreach( $fields as &$field )
{
$field = 'LOCATE(\'yform:'.$locator_table.'/'.$locator_id.'\','.$sql->escapeIdentifier($field).')';
}
return implode( ' OR ',$fields );
}

}
69 changes: 57 additions & 12 deletions plugins/documentation/docs/de_de/howto_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,12 @@ wobei wiederum xxx der Name aus dem Profil ist bzw. der Tabellenname ohne führe

Beispiel:
```
profiles_buttons_yform_option_artikel = Artikel
profiles_buttons_yform_option_kunden = Kunden
profiles_buttons_yform_option_bestellung = Bestellung
profiles_buttons_yform_option_shop_artikel = Artikel
profiles_buttons_yform_option_shop_kunden = Kunden
profiles_buttons_yform_option_shop_bestellung = Bestellung
```

Hat man den Datensatz ausgewählt, wird ein Link-Eintrag im Editorfeld erzeugt, dessen URL dem Schema `yform:rex_xxx/nnn` folgt. Dabei ist xxx der Name des Eintrags und nnn die Satznummer (Feld `id`) des ausgewählten Datensatzes.
Hat man den Datensatz ausgewählt, wird ein Link-Eintrag im Editorfeld erzeugt, dessen URL dem Schema `yform:rex_xxx/nnn` folgt. Dabei ist xxx der Name der Tabelle und nnn die Satznummer (Feld `id`) des ausgewählten Datensatzes.

```
/yform:rex_shop_artikel/22
Expand All @@ -305,7 +305,7 @@ Für die Ausgabe werden die Pseudo-URLs in eine konkrete Url umgewandelt. Dabei

#### URL-Auflösung im Frondend

Per default werden die Links umgewandelt in 'javascript:void();', also neutralisiert.
Per default werden die Links umgewandelt in 'javascript:void(0);', also neutralisiert.

Über eine eigenen Callback-Funktion können die individuellen Links erzeugt werden. Die Callback-Methode erhält ein
preg-match-Array mit den Elementen `table_name` und `id`. Die Funktion muss daraus die URL aufbauen und den String
Expand Down Expand Up @@ -347,10 +347,19 @@ markitup::$yform_callback = function ($link) {
Es steht eine Funktion zur Verfügung, mit der Yform-Links in den Textfeldern überprüft werden können

```php
markitup::yformLinkInUse( $table_name, $data_id, $tableset=null, $fullResult=false )
markitup::yformLinkInUse( $table_name, $data_id, $tableset=null, $result=false )
```
Die Funktion überprüft für die angegebenen Tabellen (`$tableset`) in den Feldern vom Typ `text`, `mediumtext` und `varchar...`, ob
in ihnen der zu prüfende Link (`$table_name, $data_id`) vorkommt.

Für `$type_in_scope` ist in der Klasse `markitup` die Vorgabe
```php
static $type_in_scope = [
'varchar' => 'Type LIKE \'varchar%\'',
'text' => 'Type = \'text\'',
'mediumtext' => 'Type = \'mediumtext\'',
];
```
Die Funktion überprüft für die angegebenen Tabllen in den Feldern vom Typ `text` und vom Typ `varchar...`, ob
in ihnen der zu prüfende Link vorkommt.

Beispiel:
- Aus der YForm-Tabelle `rex_shop_kunde` soll der Datensatz `123` wird gelöscht werden.
Expand All @@ -362,7 +371,7 @@ Beispiel:
| $table_name | Der Name der Tabelle, deren Eintrag geprüft wird | rex_shop_kunde |
| $data_id | Die ID des Datensatzes, der geprüft wird | 123 |
| $tableset | Die Liste der Tabellen, in denen nach dem Link gesucht wird | 1 |
| $fullResult | wenn TRUE werden die IDs aller gefundenen referenzen zurückgemeldet, sonst nur TRUE/FALSE | |
| $result | Suchverhalten (false,true,Zahl) | |


Für `$tableset` gibt es die Varianten
Expand All @@ -373,9 +382,10 @@ Für `$tableset` gibt es die Varianten
- `['tabelle_1',...]` = nur die Liste der angegebenen Tabellen durchsuchen.
- alle anderen Eingaben => keine Suche, Rückmeldung ist `false` = nicht in Benutzung

Im Normalfall bricht die Funktion nach dem ersten gefundenen Eintrag bereits mit TRUE ab.
Mit `$fullResult = true` wird stets eine Suche über alle angegebenen Tabellen durchgeführt und alle
gefundenen Einträge als Array der Satznummern (id) zurückgemeldet.
Im Normalfall bricht die Funktion nach dem ersten gefundenen Eintrag bereits mit `return true` ab.
Mit `$esult = true` wird stets eine Suche über alle angegebenen Tabellen durchgeführt und alle
gefundenen Einträge als Array der Satznummern (id) zurückgemeldet. Alternativ kann auch eine Zahl angegeben werden
`$result = 4`; dann werden je Tabelle maximal n (hier 4) IDs zurückgemeldet.

Die Funktion kann z.B. über den Extension-Point `YFORM_DATA_DELETE` genutzt werden; im Beispiel wird die YForm-Tabelle `rex_shop_kunde` überwacht:

Expand All @@ -387,6 +397,41 @@ Die Funktion kann z.B. über den Extension-Point `YFORM_DATA_DELETE` genutzt wer
});
```

↑ [zurück zur Übersicht](#top)

#### Id is in Use - Löschen absichern in eigenen Abfragen

Zusätzlich zur allgemeinen Methode `markitup::yformLinkInUse(...)` kann man einfach eigene Abfragen
konzipieren. Hierzu liefert die Methode
```php
markitup::yformInUseWhere( $target_table, $table_name, $data_id, $type_in_scope=null, $fields_in_scope=null )
```
eine massgeschneiderte Where-Klausel. Z.B. Kann die Suche nach YForm-Links mit der Suche nach anderen
Löschausschlußkriterien in derselben Tabelle kombiniert werden oder die recht pauschale Vorgehensweise
von `yformLinkInUse` feiner eingestellt werden.

| Parameter | Erklärung | Beispiel |
|--|--|--|
| $target_table | Der Name der Tabelle, in der nach dem Link gesucht wird | rex_article_slice |
| $table_name | Der Name der Tabelle, deren Eintrag geprüft wird | rex_shop_kunde |
| $data_id | Die ID des Datensatzes, der geprüft wird | 123 |
| $type_in_scope | Array; legt fest, welche Feldtypen durchsucht werden | ['Type LIKE "%text"'] |
| $fields_in_scope | Array; legt fest, welche Felder durchsucht werden | ['value1','value2'] |

Alle Elemente in `$type_in_scope` bzw. `$fields_in_scope` sind ODER-verknüpft. Beide untereinander sind
jedoch UND-verknüpft.

Die `target_table` wird für die Suche nach den Feldern benutzt, die die angegeben Typen haben, und
um sicherzustellen, dass die Felder ($`fields_in_scope`) in der Tabelle vorkommen.

Ist `$type_in_scope` nicht angegeben (`null`), wird auf `markitup::$type_in_scope` zurückgegriffen. Ein leerer
`$type_in_scope` muss als `[]` angegeben werden.

* Wird nur `$type_in_scope` angegeben, werden alle Felder der angegebenen Typen untersucht.
* Wird nur `$fields_in_scope` angegeben und `$type_in_scope` ist leer (`[]`), werden alle angegebenen Felder untersucht.
* Werden beide angegeben, werden nur Felder untersucht, die einem der angegebenen Typen entsprechen UND in der Feldliste vorkommen.


↑ [zurück zur Übersicht](#top)

<a name="beispiele"></a>
Expand Down