├── plugins
└── .redaxo
├── pages
├── index.php
└── settings.php
├── .travis.yml
├── install.php
├── package.yml
├── .github
└── workflows
│ └── publish-to-redaxo.yml
├── update.php
├── lang
├── pt_br.lang
├── en_gb.lang
├── sv_se.lang
├── de_de.lang
└── es_es.lang
├── LICENSE
├── lib
├── command.php
├── synchronizer_item.php
├── manager.php
├── synchronizer_default.php
└── synchronizer.php
├── boot.php
├── README.md
└── CHANGELOG.md
/plugins/.redaxo:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pages/index.php:
--------------------------------------------------------------------------------
1 | i18n('name'));
6 |
7 | rex_be_controller::includeCurrentPageSubPath();
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - '7.1'
5 |
6 | cache:
7 | directories:
8 | - $HOME/.composer/cache
9 |
10 | before_install:
11 | - phpenv config-rm xdebug.ini || echo "xdebug not available"
12 |
13 | script:
14 | - composer require --dev friendsofredaxo/linter
15 | - vendor/bin/rexlint
16 |
--------------------------------------------------------------------------------
/install.php:
--------------------------------------------------------------------------------
1 | hasConfig()) {
6 | $this->setConfig([
7 | 'templates' => true,
8 | 'modules' => true,
9 | 'actions' => true,
10 | 'yform_email' => true,
11 | 'sync_frontend' => true,
12 | 'sync_backend' => true,
13 | 'rename' => true,
14 | 'dir_suffix' => true,
15 | 'prefix' => false,
16 | 'umlauts' => false,
17 | 'delete' => true,
18 | ]);
19 | }
20 |
--------------------------------------------------------------------------------
/package.yml:
--------------------------------------------------------------------------------
1 | package: developer
2 | version: '3.9.3'
3 | author: Friends Of REDAXO
4 | supportpage: https://github.com/FriendsOfREDAXO/developer
5 |
6 | page:
7 | title: translate:name
8 | perm: admin
9 | icon: rex-icon fa-code
10 | subpages:
11 | settings: { title: translate:settings }
12 | readme: { title: translate:readme, subPath: README.md }
13 |
14 | console_commands:
15 | developer:sync: rex_developer_command
16 |
17 | requires:
18 | php:
19 | version: '>=5.5'
20 | extensions: [iconv]
21 | redaxo: ^5.2
22 |
--------------------------------------------------------------------------------
/.github/workflows/publish-to-redaxo.yml:
--------------------------------------------------------------------------------
1 | name: Publish release
2 |
3 | on:
4 | release:
5 | types:
6 | - published
7 |
8 | jobs:
9 | redaxo_publish:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v3
13 | - uses: FriendsOfREDAXO/installer-action@v1
14 | with:
15 | myredaxo-username: ${{ secrets.MYREDAXO_USERNAME }}
16 | myredaxo-api-key: ${{ secrets.MYREDAXO_API_KEY }}
17 | description: ${{ github.event.release.body }}
18 |
--------------------------------------------------------------------------------
/update.php:
--------------------------------------------------------------------------------
1 | getVersion(), '3.4.1', '<')) {
8 | rex_file::delete($this->getDataPath('actions/.rex_id_list'));
9 | rex_file::delete($this->getDataPath('modules/.rex_id_list'));
10 | rex_file::delete($this->getDataPath('templates/.rex_id_list'));
11 | }
12 |
13 | if (rex_string::versionCompare($this->getVersion(), '3.5.0', '<')) {
14 | $this->setConfig('sync_frontend', true);
15 | }
16 |
17 | if (rex_string::versionCompare($this->getVersion(), '3.6.0', '<')) {
18 | $this->setConfig('sync_backend', true);
19 | }
20 |
21 | if (rex_string::versionCompare($this->getVersion(), '3.6.0-beta2', '<')) {
22 | $this->setConfig('dir_suffix', false);
23 | }
24 |
--------------------------------------------------------------------------------
/lang/pt_br.lang:
--------------------------------------------------------------------------------
1 | developer_name = Programador
2 | developer_settings = Configurações
3 | developer_templates = Sincronizar templates
4 | developer_modules = Sincronizar módulos
5 | developer_actions = Sincronizar ações
6 | developer_sync_frontend = Sincronizar no frontend (somente se registrado como administrador no backend)
7 | developer_sync_backend = Sincronizar no backend (somente se registrado como administrador)
8 | developer_rename = Atualizar nomes de arquivo e diretórios automaticamente
9 | developer_prefix = Prefixo do nome do arquivo (contem ID e nome)
10 | developer_umlauts = Manter acentos nos nomes
11 | developer_delete = Deletar item do diretório depois de deletar item no backend
12 | developer_dir = Diretório
13 | developer_save = Salvar configurações
14 | developer_saved = Configurações foram salvas
15 | developer_error = Um erro ocorreu
16 |
--------------------------------------------------------------------------------
/lang/en_gb.lang:
--------------------------------------------------------------------------------
1 | developer_name = Developer
2 |
3 | developer_settings = Settings
4 | developer_templates = Synchronize templates
5 | developer_modules = Synchronize modules
6 | developer_actions = Synchronize actions
7 | developer_yform_email = YForm: Synchronize email templates
8 | developer_sync_frontend = Synchronize in frontend (only if signed in as admin in backend)
9 | developer_sync_backend = Synchronize in backend (only if signed in as admin)
10 | developer_rename = Update file and directory names automatically
11 | developer_dir_suffix = Dir names with id suffix
12 | developer_prefix = Filename prefix (contains ID and name)
13 | developer_umlauts = Keep umlauts in names (deprecated; will be removed in next major version)
14 | developer_delete = Delete item directory after deleting item in backend
15 | developer_dir = Directory
16 | developer_save = Save settings
17 | developer_saved = Settings have been saved
18 | developer_error = An error occured
19 |
20 | developer_readme = Readme
21 |
--------------------------------------------------------------------------------
/lang/sv_se.lang:
--------------------------------------------------------------------------------
1 | developer_name = Developer
2 |
3 | developer_settings = Inställningar
4 | developer_templates = Synkronisera mallar
5 | developer_modules = Synkronisera moduler
6 | developer_actions = Synkronisera aktioner
7 | developer_yform_email = YForm: Synkronisera e-postmallar
8 | developer_sync_frontend = Synkronisera i frontend (endast om du är inloggad som administratör i backend)
9 | developer_sync_backend = Synkronisera i backend (endast om du är inloggad som administratör)
10 | developer_rename = Uppdatera fil- och katalognamn automatiskt
11 | developer_dir_suffix = Mappnamn med ID som suffix
12 | developer_prefix = Filnamn prefix (innehåller ID och namn)
13 | developer_umlauts = Håll umlauts i namn
14 | developer_delete = Ta bort artikelkatalog efter att du har raderat objektet i backend
15 | developer_dir = Mapp
16 | developer_save = Spara inställningarna
17 | developer_saved = Inställningarna har sparats
18 | developer_error = Det uppstod ett fel
19 |
20 | developer_readme = Hjälp
21 |
--------------------------------------------------------------------------------
/lang/de_de.lang:
--------------------------------------------------------------------------------
1 | developer_name = Developer
2 |
3 | developer_settings = Einstellungen
4 | developer_templates = Templates synchronisieren
5 | developer_modules = Module synchronisieren
6 | developer_actions = Actions synchronisieren
7 | developer_yform_email = YForm: E-Mail-Templates synchronisieren
8 | developer_sync_frontend = Im Frontend synchronisieren (nur wenn als Admin im Backend eingeloggt)
9 | developer_sync_backend = Im Backend synchronisieren (nur wenn als Admin eingeloggt)
10 | developer_rename = Datei- und Ordnernamen aktuell halten
11 | developer_dir_suffix = Ordnernamen mit ID als Suffix
12 | developer_prefix = Präfix für Dateinamen (enthält ID und Name)
13 | developer_umlauts = Umlaute in Namen beibehalten (Deprecated; die Option wird in der nächsten Major-Version wegfallen und somit immer deaktiviert sein)
14 | developer_delete = Item-Ordner löschen nach dem Löschen eines Items über das Backend
15 | developer_dir = Ordner
16 | developer_save = Einstellungen speichern
17 | developer_saved = Die Einstellungen wurden gespeichert.
18 | developer_error = Es ist ein Fehler aufgetreten.
19 |
20 | developer_readme = Hilfe
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Friends Of REDAXO
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/lang/es_es.lang:
--------------------------------------------------------------------------------
1 | developer_name = Desarrollador
2 |
3 | developer_settings = Ajustes
4 | developer_templates = Sincronizar plantillas
5 | developer_modules = Sincronizar módulos
6 | developer_actions = Sincronizar acciones
7 | developer_yform_email = YForm: sincronizar plantillas de correo electrónico
8 | developer_sync_frontend = Sincronizar en frontend (solo iniciado sesión como administrador en back-end)
9 | developer_sync_backend = Sincronizar en el backend (solo si está conectado como administrador)
10 | developer_rename = Mantenga actualizados los nombres de archivos y carpetas
11 | developer_dir_suffix = Nombre de la carpeta con ID como sufijo
12 | developer_prefix = Prefijo de nombre de archivo (contiene ID y nombre)
13 | developer_umlauts = Mantenga umlauts en los nombres (obsoleto, la opción desaparecerá en la siguiente versión principal y por lo tanto siempre estará deshabilitada)
14 | developer_delete = Eliminar carpeta de elementos después de eliminar un elemento a través del servidor
15 | developer_dir = Directorio
16 | developer_save = Guardar configuraciones
17 | developer_saved = La configuración ha sido guardada.
18 | developer_error = Un error ha ocurrido
19 |
20 | developer_readme = Léame
21 |
--------------------------------------------------------------------------------
/lib/command.php:
--------------------------------------------------------------------------------
1 | setName('developer:sync')
14 | ->setDescription('Synchronizes the developer files')
15 | ->addOption('force-db', null, InputOption::VALUE_NONE, 'Force the current status in db, files will be overridden')
16 | ->addOption('force-files', null, InputOption::VALUE_NONE, 'Force the current status in file system, db data will be overridden')
17 | ;
18 | }
19 |
20 | protected function execute(InputInterface $input, OutputInterface $output)
21 | {
22 | $io = $this->getStyle($input, $output);
23 |
24 | $io->title('Developer Sync');
25 |
26 | $forceDb = $input->getOption('force-db');
27 | $forceFiles = $input->getOption('force-files');
28 |
29 | if ($forceDb && $forceFiles) {
30 | throw new InvalidArgumentException('Options --force-db and --force-files can not be used at once.');
31 | }
32 |
33 | $force = false;
34 | if ($forceDb) {
35 | $force = rex_developer_synchronizer::FORCE_DB;
36 | } elseif ($forceFiles) {
37 | $force = rex_developer_synchronizer::FORCE_FILES;
38 | }
39 |
40 | rex_developer_manager::start($force);
41 |
42 | $io->success('Synchronized developer files.');
43 |
44 | return 0;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/boot.php:
--------------------------------------------------------------------------------
1 | isAvailable() && rex_media_manager::getMediaType() && rex_media_manager::getMediaFile()) {
12 | return;
13 | }
14 |
15 | if (
16 | !rex::isBackend() && $this->getConfig('sync_frontend') ||
17 | rex::getUser() && rex::isBackend() && $this->getConfig('sync_backend')
18 | ) {
19 | rex_extension::register('PACKAGES_INCLUDED', function () {
20 | if (rex::isDebugMode() || ($user = rex_backend_login::createUser()) && $user->isAdmin()) {
21 | rex_developer_manager::start();
22 | }
23 | });
24 | }
25 |
26 | rex_extension::register('EDITOR_URL', function (rex_extension_point $ep) {
27 | if (!preg_match('@^rex:///(template|module|action)/(\d+)(?:/([^/]+))?@', $ep->getParam('file'), $match)) {
28 | return null;
29 | }
30 |
31 | $type = $match[1];
32 | $id = $match[2];
33 |
34 | if (!$this->getConfig($type.'s')) {
35 | return null;
36 | }
37 |
38 | if ('template' === $type) {
39 | $subtype = 'template';
40 | } elseif (!isset($match[3])) {
41 | return null;
42 | } else {
43 | $subtype = $match[3];
44 | }
45 |
46 | $path = rtrim(rex_developer_manager::getBasePath(), '/\\').'/'.$type.'s';
47 |
48 | if (!$files = rex_developer_synchronizer::glob("$path/*/$id.rex_id", GLOB_NOSORT)) {
49 | return null;
50 | }
51 |
52 | $path = dirname($files[0]);
53 |
54 | if (!$files = rex_developer_synchronizer::glob("$path/*$subtype.php", GLOB_NOSORT)) {
55 | return null;
56 | }
57 |
58 | return rex_editor::factory()->getUrl($files[0], $ep->getParam('line'));
59 | }, rex_extension::LATE);
60 |
--------------------------------------------------------------------------------
/lib/synchronizer_item.php:
--------------------------------------------------------------------------------
1 | content)
22 | */
23 | public function __construct($id, $name, $updated, array $files = array())
24 | {
25 | $this->id = $id;
26 | $this->name = $name;
27 | $this->updated = $updated;
28 | $this->files = $files;
29 | }
30 |
31 | /**
32 | * Sets the ID
33 | *
34 | * @param int $id
35 | */
36 | public function setId($id)
37 | {
38 | $this->id = $id;
39 | }
40 |
41 | /**
42 | * Returns the ID
43 | *
44 | * @return int
45 | */
46 | public function getId()
47 | {
48 | return $this->id;
49 | }
50 |
51 | /**
52 | * Sets the name
53 | *
54 | * @param string $name
55 | */
56 | public function setName($name)
57 | {
58 | $this->name = $name;
59 | }
60 |
61 | /**
62 | * Returns the name
63 | *
64 | * @return string
65 | */
66 | public function getName()
67 | {
68 | return $this->name;
69 | }
70 |
71 | /**
72 | * Sets the update timestamp
73 | *
74 | * @param int $updated
75 | */
76 | public function setUpdated($updated)
77 | {
78 | $this->updated = $updated;
79 | }
80 |
81 | /**
82 | * Returns the update timestamp
83 | *
84 | * @return int
85 | */
86 | public function getUpdated()
87 | {
88 | return $this->updated;
89 | }
90 |
91 | /**
92 | * Sets the item files and their content
93 | *
94 | * @param string[] $files Array of item files and their content (file=>content)
95 | */
96 | public function setFiles(array $files)
97 | {
98 | $this->files = $files;
99 | }
100 |
101 | /**
102 | * Sets the content of an item file
103 | *
104 | * @param string $file File name
105 | * @param string|callable():string $content Content
106 | */
107 | public function setFile($file, $content)
108 | {
109 | $this->files[$file] = $content;
110 | }
111 |
112 | /**
113 | * Returns all item files and their content
114 | *
115 | * @return string[] Array of all item files and their content (file=>content)
116 | */
117 | public function getFiles()
118 | {
119 | return $this->files;
120 | }
121 |
122 | /**
123 | * Returns the content of the given item file
124 | *
125 | * @param string $file File name
126 | * @return string Content
127 | */
128 | public function getFile($file)
129 | {
130 | if (!isset($this->files[$file])) {
131 | return '';
132 | }
133 | if ((!is_string($file) || strlen($file) < 200) && is_callable($this->files[$file])) {
134 | $this->files[$file] = call_user_func($this->files[$file]);
135 | }
136 | return $this->files[$file];
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | REDAXO-AddOn: developer
2 | =======================
3 |
4 | Das AddOn ermöglicht es, die Templates, Module, Actions, sowie die E-Mail-Templates von YForm über das Dateisystem (und somit mit beliebigem Editor) zu bearbeiten, bzw. neu anzulegen.
5 |
6 | 
7 |
8 | Mindestvoraussetzungen
9 | ----------------------
10 |
11 | * PHP 5.5
12 | * REDAXO 5.2
13 |
14 | Installation
15 | ------------
16 |
17 | 1. Über Installer laden oder Zip-Datei im AddOn-Ordner entpacken, der Ordner muss „developer“ heißen.
18 | 2. AddOn installieren und aktivieren.
19 | 3. Gegebenfalls die Einstellungen auf der Developer-Page anpassen. Standardmäßig sind alle drei Sychronisationen (Templates/Module/Actions) aktiviert.
20 |
21 | Benutzung
22 | ---------
23 |
24 | * Innerhalb des Ordners `redaxo/data/addons/developer` wird bei Bedarf jeweils ein Unterordner für Templates, Module und Actions angelegt.
25 | * Innerhalb der Unterordner wird für jedes einzelne Item (Template/Modul/Action) ein weiterer Unterordner angelegt.
26 | * Diese Ordner enthalten dann die Dateien, die synchronisiert werden. Neben der `metadata.yml`, welche unter anderem den Namen des Items enthält, sind dies die folgenden:
27 | - Templates: `template.php`
28 | - Module: `input.php`, `output.php`
29 | - Actions: `preview.php`, `presave.php`, `postsave.php`
30 | * Es wird nur synchronisiert, wenn man im Backend als Admin eingeloggt ist, dann aber auch, wenn man das Frontend aufruft.
31 | * Es können neue Items über das Dateisystem angelegt werden. Dazu genügt es einen neuen Ordner anzulegen mit mindestens einer der aufgelisteten Dateien.
32 | * Wenn die automatische Umbenennung deaktiviert ist, können die Dateien individuell umbenannt werden, sie müssen aber mit dem Standardnamen enden. Die `template.php` kann also zum Beispiel in `navigation.template.php` umbenannt werden. Developer wird die dann trotzdem finden und den Namen beibehalten. Optional kann ein Präfix bestehend aus ID und Name automatisch hinzugefügt werden.
33 | * Der Item-Ordner kann beliebig umbenannt werden. Als Zuordnung dient eine Datei `X.rex-id` innerhalb des Ordners, die nicht gelöscht werden darf.
34 | * Bei Umbennung über das Backend ändert Developer nichts an den Ordner- und Dateinamen, nur der Name innerhalb der `metadata.yml` wird aktualisiert. Über dieses Feld kann auch der Name im Backend über das Dateisystem geändert werden.
35 | * Nach dem Löschen eines Item-Ordners (oder einzelner Dateien) werden diese neu angelegt. Die Items müssen also regulär über das Backend gelöscht werden.
36 | * Nach dem Löschen eines Items über das Backend wird der Sychronisationsordner gelöscht, wenn die entsprechende Option nicht deaktivert ist. Ansonsten wird nur die `.rex-id` durch eine `.rex-ignore` ersetzt.
37 |
38 |
39 | Hinweise zur Synchronisation im Frontend
40 | ------------
41 | * Damit die Synchronisation im Frontend funktioniert, muss hierzu die entsprechende Checkbox in den Einstellungen von developer aktiviert werden.
42 | * Damit die Synchronisation nach dem Speichern direkt im Frontend funktioniert, muss entweder der Debug-Modus aktiviert sein, oder die Seite im Frontend über die selbe Domain aufgerufen werden, mit welcher man sich im Backend eingeloggt hat, da ansonsten die Backend-Session nicht mit dem Frontend übereinstimmt (Beispiel: im Backend mit www. eingeloggt aber das Frontend ohne www. aufgerufen). Selbes gilt in Multidomain-Umgebungen und für http/https.
43 |
44 |
45 | Fehlerbehebung
46 | ---------
47 | Falls die Synchronisation von aktualisierten Dateien fehlschlägt, kann der Grund ein falscher Timestamp sein. Das `updatedate` in der Datenbank muss älter sein als der Zeitstempel der hochgeladenen Datei.
48 |
49 |
50 | Eigene Synchronisationen
51 | ------------------------
52 |
53 | Über PlugIns oder andere AddOns ist es möglich, eigene Sychronisationen mit dem Dateisystem hinzuzufügen. Details dazu gibt es im [Wiki](https://github.com/friendsofredaxo/developer/wiki/Eigene-Synchronisationen).
54 |
--------------------------------------------------------------------------------
/pages/settings.php:
--------------------------------------------------------------------------------
1 | setConfig(rex_post('config', [
7 | ['templates', 'bool'],
8 | ['modules', 'bool'],
9 | ['actions', 'bool'],
10 | ['yform_email', 'bool'],
11 | ['sync_frontend', 'bool'],
12 | ['sync_backend', 'bool'],
13 | ['rename', 'bool'],
14 | ['dir_suffix', 'bool'],
15 | ['prefix', 'bool'],
16 | ['umlauts', 'bool'],
17 | ['delete', 'bool'],
18 | ]));
19 |
20 | echo rex_view::success($this->i18n('saved'));
21 | }
22 |
23 | $content = '