Implement Blake3 hashing in CDokumente; update related metadata and localization files
This commit is contained in:
@@ -35,22 +35,24 @@ class CDokumente extends \Espo\Core\Hooks\Base
|
||||
return;
|
||||
}
|
||||
|
||||
// Berechne neue Hashes
|
||||
$newMd5 = hash_file('md5', $filePath);
|
||||
$newSha256 = hash_file('sha256', $filePath);
|
||||
// Berechne Blake3 Hash
|
||||
$fileContent = file_get_contents($filePath);
|
||||
if ($fileContent === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newBlake3 = bin2hex(blake3($fileContent));
|
||||
|
||||
// Setze Hashes
|
||||
$entity->set('md5sum', $newMd5);
|
||||
$entity->set('sha256', $newSha256);
|
||||
// Setze Hash
|
||||
$entity->set('blake3hash', $newBlake3);
|
||||
|
||||
// Bestimme Status
|
||||
if ($entity->isNew()) {
|
||||
$entity->set('fileStatus', 'new');
|
||||
} else {
|
||||
$oldMd5 = $entity->getFetched('md5sum');
|
||||
$oldSha256 = $entity->getFetched('sha256');
|
||||
$oldBlake3 = $entity->getFetched('blake3hash');
|
||||
|
||||
if ($oldMd5 !== $newMd5 || $oldSha256 !== $newSha256) {
|
||||
if ($oldBlake3 !== $newBlake3) {
|
||||
$entity->set('fileStatus', 'changed');
|
||||
} else {
|
||||
$entity->set('fileStatus', 'synced');
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"dokument": "Download",
|
||||
"preview": "Vorschau",
|
||||
"ydocumentuuid": "Y-Document-UUID",
|
||||
"md5sum": "MD5-Prüfsumme",
|
||||
"sha256": "SHA256-Prüfsumme",
|
||||
"blake3hash": "Blake3-Hash",
|
||||
"fileStatus": "Datei-Status",
|
||||
"contactsvmhdokumente": "Freigegebene Nutzer",
|
||||
"vmhMietverhltnisesDokumente": "Mietverhältnisse",
|
||||
@@ -41,6 +40,7 @@
|
||||
"Create CDokumente": "Dokument erstellen"
|
||||
},
|
||||
"tooltips": {
|
||||
"blake3hash": "Kryptografischer Blake3-Hash der Datei (schneller und sicherer als MD5/SHA256)",
|
||||
"fileStatus": "Status der Datei: new = neu hochgeladen, changed = geändert, synced = synchronisiert"
|
||||
},
|
||||
"options": {
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
"vmhErstgespraechsdokumente": "Initial Consultations",
|
||||
"vmhRumungsklagesdokumente": "Eviction Lawsuits",
|
||||
"kuendigungDokumente": "Terminations",
|
||||
"md5sum": "MD5 Checksum",
|
||||
"sha256": "SHA256 Checksum",
|
||||
"blake3hash": "Blake3 Hash",
|
||||
"beteiligte2dokumente": "Parties",
|
||||
"mietobjekt2dokumente": "Properties",
|
||||
"mietinkassosdokumente": "Rent Collection",
|
||||
@@ -47,6 +46,7 @@
|
||||
"listForAIKnowledge": "List for AI Knowledge"
|
||||
},
|
||||
"tooltips": {
|
||||
"blake3hash": "Cryptographic Blake3 hash of the file (faster and more secure than MD5/SHA256)",
|
||||
"fileStatus": "File status: new = newly uploaded, changed = modified, synced = synchronized"
|
||||
},
|
||||
"options": {
|
||||
|
||||
@@ -61,13 +61,9 @@
|
||||
"name": "fileStatus"
|
||||
},
|
||||
{
|
||||
"name": "md5sum"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"name": "sha256"
|
||||
}
|
||||
"name": "blake3hash"
|
||||
},
|
||||
{}
|
||||
]
|
||||
],
|
||||
"dynamicLogicVisible": null,
|
||||
|
||||
@@ -59,21 +59,14 @@
|
||||
"readOnlyAfterCreate": false,
|
||||
"isCustom": true
|
||||
},
|
||||
"md5sum": {
|
||||
"blake3hash": {
|
||||
"type": "varchar",
|
||||
"maxLength": 32,
|
||||
"maxLength": 64,
|
||||
"copyToClipboard": true,
|
||||
"readOnlyAfterCreate": true,
|
||||
"options": [],
|
||||
"isCustom": true
|
||||
},
|
||||
"sha256": {
|
||||
"type": "varchar",
|
||||
"maxLength": 64,
|
||||
"readOnlyAfterCreate": true,
|
||||
"options": [],
|
||||
"isCustom": true,
|
||||
"copyToClipboard": true
|
||||
"tooltip": true
|
||||
},
|
||||
"puls": {
|
||||
"type": "link",
|
||||
@@ -298,14 +291,9 @@
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"md5sum": {
|
||||
"blake3hash": {
|
||||
"columns": [
|
||||
"md5sum"
|
||||
]
|
||||
},
|
||||
"sha256": {
|
||||
"columns": [
|
||||
"sha256"
|
||||
"blake3hash"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"beforeSaveScript": "// Automatische x.AI Sync-Status Verwaltung\n\n// Fall 1: xaiId wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('xaiId') != null &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n// Fall 2: xaiId wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('xaiId') == null &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat xaiId und relevante Felder haben sich geändert\nelse if (\n xaiId != null &&\n xaiSyncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('md5sum') ||\n attribute\\isChanged('sha256')\n )\n) {\n xaiSyncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT xaiId → pending_sync\nelse if (\n entity\\isNew() &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE xaiId → no_sync\nelse if (\n entity\\isNew() &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n\n// Automatische Advoware Sync-Status Verwaltung\n\n// Fall 1: aktennr wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('aktennr') != null &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}\n// Fall 2: aktennr wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('aktennr') == null &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat aktennr und relevante Felder haben sich geändert\nelse if (\n aktennr != null &&\n syncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('md5sum') ||\n attribute\\isChanged('sha256')\n )\n) {\n syncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT aktennr → pending_sync\nelse if (\n entity\\isNew() &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE aktennr → no_sync\nelse if (\n entity\\isNew() &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}"
|
||||
"beforeSaveScript": "// Automatische x.AI Sync-Status Verwaltung\n\n// Fall 1: xaiId wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('xaiId') != null &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n// Fall 2: xaiId wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('xaiId') == null &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat xaiId und relevante Felder haben sich geändert\nelse if (\n xaiId != null &&\n xaiSyncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('blake3hash')\n )\n) {\n xaiSyncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT xaiId → pending_sync\nelse if (\n entity\\isNew() &&\n xaiId != null\n) {\n xaiSyncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE xaiId → no_sync\nelse if (\n entity\\isNew() &&\n xaiId == null\n) {\n xaiSyncStatus = 'no_sync';\n}\n\n// Automatische Advoware Sync-Status Verwaltung\n\n// Fall 1: aktennr wurde gelöscht (war vorher vorhanden, jetzt leer)\nif (\n attribute\\fetched('aktennr') != null &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}\n// Fall 2: aktennr wird neu gesetzt (war vorher leer, jetzt gefüllt)\nelse if (\n attribute\\fetched('aktennr') == null &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 3: Dokument hat aktennr und relevante Felder haben sich geändert\nelse if (\n aktennr != null &&\n syncStatus != 'no_sync' &&\n (\n attribute\\isChanged('name') ||\n attribute\\isChanged('description') ||\n attribute\\isChanged('dokumentId') ||\n attribute\\isChanged('blake3hash')\n )\n) {\n syncStatus = 'unclean';\n}\n// Fall 4: Bei neuem Dokument MIT aktennr → pending_sync\nelse if (\n entity\\isNew() &&\n aktennr != null\n) {\n syncStatus = 'pending_sync';\n}\n// Fall 5: Bei neuem Dokument OHNE aktennr → no_sync\nelse if (\n entity\\isNew() &&\n aktennr == null\n) {\n syncStatus = 'no_sync';\n}"
|
||||
}
|
||||
|
||||
87
custom/scripts/install_blake3.sh
Executable file
87
custom/scripts/install_blake3.sh
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
# Blake3 PHP Extension Installation Script
|
||||
# Für EspoCRM Docker Container
|
||||
|
||||
set -e # Beende bei Fehler
|
||||
|
||||
echo "========================================="
|
||||
echo "Blake3 PHP Extension Installation"
|
||||
echo "========================================="
|
||||
|
||||
# Schritt 1: Build-Tools installieren
|
||||
echo ""
|
||||
echo "Schritt 1: Installiere Build-Tools..."
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
git \
|
||||
build-essential \
|
||||
autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
pkg-config \
|
||||
curl \
|
||||
libcurl4-openssl-dev
|
||||
|
||||
# PHP-Dev ist bereits im Image vorhanden
|
||||
echo "PHP Development headers: $(php-config --version)"
|
||||
|
||||
# Schritt 2: Blake3 C-Bibliothek klonen
|
||||
echo ""
|
||||
echo "Schritt 2: Lade Blake3 C-Bibliothek..."
|
||||
cd /tmp
|
||||
rm -rf BLAKE3 php-blake3
|
||||
git clone https://github.com/BLAKE3-team/BLAKE3.git
|
||||
cd BLAKE3/c
|
||||
gcc -shared -O3 -o libblake3.so blake3.c blake3_dispatch.c blake3_portable.c blake3_sse2_x86-64_unix.S blake3_sse41_x86-64_unix.S blake3_avx2_x86-64_unix.S blake3_avx512_x86-64_unix.S -fPIC
|
||||
cp libblake3.so /usr/local/lib/
|
||||
ldconfig
|
||||
|
||||
# Schritt 3: PHP Blake3 Extension klonen und kompilieren
|
||||
echo ""
|
||||
echo "Schritt 3: Kompiliere PHP Blake3 Extension..."
|
||||
cd /tmp
|
||||
git clone https://github.com/cypherbits/php-blake3.git
|
||||
cd php-blake3
|
||||
|
||||
phpize
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
# Schritt 4: Extension aktivieren
|
||||
echo ""
|
||||
echo "Schritt 4: Aktiviere Blake3 Extension..."
|
||||
PHP_INI_DIR=$(php -i | grep "Scan this dir for additional .ini files" | cut -d'>' -f2 | xargs)
|
||||
if [ -z "$PHP_INI_DIR" ]; then
|
||||
PHP_INI_DIR="/usr/local/etc/php/conf.d"
|
||||
fi
|
||||
|
||||
echo "extension=blake3.so" > ${PHP_INI_DIR}/99-blake3.ini
|
||||
|
||||
# Schritt 5: Verifizierung
|
||||
echo ""
|
||||
echo "Schritt 5: Verifiziere Installation..."
|
||||
php -m | grep -i blake3
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Blake3 Extension erfolgreich installiert!"
|
||||
php -r "echo 'Test Hash: ' . hash('blake3', 'test') . PHP_EOL;"
|
||||
else
|
||||
echo "❌ Blake3 Extension nicht geladen!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
echo ""
|
||||
echo "Schritt 6: Aufräumen..."
|
||||
cd /
|
||||
rm -rf /tmp/BLAKE3 /tmp/php-blake3
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "✅ Installation abgeschlossen!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Nächste Schritte:"
|
||||
echo "1. Starte PHP-FPM neu: service php8.4-fpm restart || pkill -USR2 php-fpm"
|
||||
echo "2. Überprüfe: php -m | grep blake3"
|
||||
echo "3. Teste: php -r \"echo hash('blake3', 'test');\""
|
||||
@@ -360,7 +360,7 @@ return [
|
||||
0 => 'youtube.com',
|
||||
1 => 'google.com'
|
||||
],
|
||||
'microtime' => 1773262547.930204,
|
||||
'microtime' => 1773264000.882682,
|
||||
'siteUrl' => 'https://crm.bitbylaw.com',
|
||||
'fullTextSearchMinLength' => 4,
|
||||
'webSocketUrl' => 'ws://api.bitbylaw.com:5000/espocrm/ws',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
return [
|
||||
'cacheTimestamp' => 1773262548,
|
||||
'microtimeState' => 1773262548.062426,
|
||||
'cacheTimestamp' => 1773264001,
|
||||
'microtimeState' => 1773264001.003279,
|
||||
'currencyRates' => [
|
||||
'EUR' => 1.0
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user