Code Monkey home page Code Monkey logo

area-net-gmbh / contentfly-cms Goto Github PK

View Code? Open in Web Editor NEW
3.0 3.0 2.0 10.25 MB

Mit der Contentfly Plattform können mobile Apps für iOS und Android unter dem Einsatz von nativen und/oder webbasierten Technologien inklusive Synchronisations-Anbindung an ein Backend-System entwickelt werden. Das Contentfly CMS kann aber auch ohne eine App-Anbindung für die Datenhaltung von Websites, Landing-Pages, Individual-Programmierung oder PIM (Product Information System) flexibel genutzt werden.

Home Page: https://www.contentfly-cms.de

License: Other

PHP 51.68% HTML 14.78% JavaScript 28.80% CSS 2.09% Twig 2.66%

contentfly-cms's Issues

Alternativer Webroot-Ordner

Möglichkeit, um einen alternativen, individuellen Webroot-Ordner anzulegen:

  • Standard appcms/public weiterhin mit ausliefern
  • Zusätliche Möglichkeit einen eigenen Webroot-Ordner anzuelegen, z.B.
    • appcms
    • custom
    • public
      • index.php
      • .htaccess

Bedingungen/Funktionen

(1) index.php (und .htaccess) muss manuell erstellt werden, mit Einbindung einer Bootstrap-Datei:
<?php require_once('../appcms/web-bootstrap.php);

(2) Symbolische Ordner-Verweise müssen aut. zur Laufzeit erstellt werden

Vorteile

  • Anpassungen an index.php/.htaccess möglich (z.B. Server-Errors), ohne Update-Problematik
  • Eigene Dateien/Unterordner (z.B. Ionic-Webapp), ohne Update-Problematik

Multi-Checkbox mit pflegbaren Optionswerten für Many2Many

(1) Neue Entitäten

  • PIM\Option
    • id, group, value
  • PIM\OptionGroup
    • id, name (unique)

(2) Neuer Typ "Checkbox"

  • Neue Annotation
    • @ORM\ManyToMany(targetEntity="Areanet\PIM\Entity\Options")
      @ORM\JoinTable(name="join_table_name", joinColumns {@ORM\JoinColumn(onDelete="CASCADE")})
      @PIM\Checkbox() // oder @PIM\Checkbox(group='gruppenname')
  • Bei der Schema-Erstellung "Types/CheckboxType->processSchema()" entweder group (wenn gesetzt) oder "Entitätname/Feldname" in OptionGroup speichern

** (3) Neuer Frontendtyp "Checkbox"**

  • Analog Multijoin

Fehler bei Installation: Couldn't find constant APP_CMS_SHOW_ID_IN_LIST, property Areanet\PIM\Entity\Base::$id.

[Semantical Error] Couldn't find constant APP_CMS_SHOW_ID_IN_LIST, property Areanet\PIM\Entity\Base::$id. #0 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php(102): Doctrine\Common\Annotations\AnnotationException::semanticalError('Couldn't find c...') #1 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(973): Doctrine\Common\Annotations\AnnotationException::semanticalErrorConstants('APP_CMS_SHOW_ID...', 'property Areane...') #2 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1039): Doctrine\Common\Annotations\DocParser->Constant() #3 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1087): Doctrine\Common\Annotations\DocParser->PlainValue() #4 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1017): Doctrine\Common\Annotations\DocParser->FieldAssignment() #5 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(884): Doctrine\Common\Annotations\DocParser->Value() #6 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(859): Doctrine\Common\Annotations\DocParser->Values() #7 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(770): Doctrine\Common\Annotations\DocParser->MethodCall() #8 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(663): Doctrine\Common\Annotations\DocParser->Annotation() #9 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(354): Doctrine\Common\Annotations\DocParser->Annotations() #10 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php(250): Doctrine\Common\Annotations\DocParser->parse('/**\n * @ORM...', 'property Areane...') #11 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php(113): Doctrine\Common\Annotations\AnnotationReader->getPropertyAnnotations(Object(ReflectionProperty)) #12 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php(125): Doctrine\Common\Annotations\CachedReader->getPropertyAnnotations(Object(ReflectionProperty)) #13 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php(280): Doctrine\Common\Annotations\CachedReader->getPropertyAnnotation(Object(ReflectionProperty), 'Doctrine\\ORM\\Ma...') #14 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php(102): Doctrine\ORM\Mapping\Driver\AnnotationDriver->loadMetadataForClass('Areanet\\PIM\\Ent...', Object(Doctrine\ORM\Mapping\ClassMetadata)) #15 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(151): Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain->loadMetadataForClass('Areanet\\PIM\\Ent...', Object(Doctrine\ORM\Mapping\ClassMetadata)) #16 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(332): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), Object(Doctrine\ORM\Mapping\ClassMetadata), false, Array) #17 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php(78): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata('Areanet\\PIM\\Ent...') #18 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(216): Doctrine\ORM\Mapping\ClassMetadataFactory->loadMetadata('Areanet\\PIM\\Ent...') #19 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(115): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor('Areanet\\PIM\\Ent...') #20 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/areanet/PIM/Controller/InstallController.php(183): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() #21 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/areanet/PIM/Controller/InstallController.php(44): Areanet\PIM\Controller\InstallController->executeInstallation(Object(Symfony\Component\HttpFoundation\Request)) #22 [internal function]: Areanet\PIM\Controller\InstallController->submitAction(Object(Symfony\Component\HttpFoundation\Request)) #23 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/symfony/http-kernel/HttpKernel.php(144): call_user_func_array(Array, Array) #24 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #25 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/silex/silex/src/Silex/Application.php(586): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/vendor/silex/silex/src/Silex/Application.php(563): Silex\Application->handle(Object(Symfony\Component\HttpFoundation\Request)) #27 /Applications/XAMPP/xamppfiles/htdocs/7gradplus/anzeigen/appcms/public/index.php(121): Silex\Application->run() #28 {main}

Login-Fehler

Nach dem Login in das Backend, wird der Token nicht korrekt gespeichert. Es muss einmalig ein erneutes Login durchgeführt werden.

Update auf Symfony 4

  • Silex-Support endet Juni 2018
  • Update/Migration Routes/Controller
  • Update/Migration DI
  • Update/Migration Middleware/Events

Erweiterter API-Endpoint /api/query

Erweiterter API-Endpoint, um beliebige Abfragen analog zur DBAL-QueryBuilder http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html stellen zu können.

Beispiele /apiv2/query

{
	select: ['field1', 'field2', 'COUNT(id) AS users'],
	from: entity
	where: {field: value},
	groupBy: field,
	having: {field: value},
	orderBy: {field1: 'ASC'},
	addOrderBy: {field2: 'DESC'},
	setFirstResult: 10, //Offfset
	setMaxResults: 20, //Limit
}

{
	select: ['alias1.field1', 'alias1.field2'],
	from: {entity1: alias1},
	innerJoin:['alias1', 'table2', 'alias2', 'alias1.id = alias2.field_id']
	where: {field: value},
	groupBy: field,
	having: {field: value}
}

{
	select: ['alias1.field1', 'alias1.field2'],
	from: {entity1: alias1},
	innerJoin:['alias1', 'table2', 'alias2', 'alias1.id = alias2.field_id']
	where: {'field1 = ? OR field2 = ?': [value1, value2]},
	andWhere: {field3: value3}
	groupBy: field,
	having: {field: value}
}

PHP Sessions absichern

ini_set('session.cookie_httponly', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_secure', 1);

HTTP-Security-Headers setzen

Bei Force-SSL-Konfiguration:
header("Strict-Transport-Security:max-age=63072000");

Allgemein
header('Content-Security-Policy: default-src 'self unsafe-inline'');
header('X-Content-Type-Options: nosniff');
header("X-Frame-Options: SAMEORIGIN");
header("X-XSS-Protection: 1; mode=block");

Bigint/Smallint-Unterstützung

IntegerType.php
return ($annotation->type == 'integer' || $annotation->type == 'bigint' || $annotation->type == 'smallint');

$DB_ID_INTEGER_TYPE = 'integer'

bootstrap.php

if (Config\Adapter::getConfig()->DB_GUID_STRATEGY) {
        define('APPCMS_ID_TYPE', 'string');
        define('APPCMS_ID_STRATEGY', 'UUID');
    } else {
        define('APPCMS_ID_TYPE', Config\Adapter::getConfig()->DB_ID_INTEGER_TYPE );
        define('APPCMS_ID_STRATEGY', 'AUTO');
    }`

Syntax Error "got 'PIM\\File" bei api/all

[Syntax Error] line 0, col 7: Error: Expected IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | \"(\" Subselect \")\" | CaseExpression, got 'PIM\\File'

Neue Events/Hooks für Schema-Generierung

pim.schema.after.classAnnotation
Wird aufgerufen, nachdem eine Klassen-Annotation verarbeitet wurde. Kann genutzt werden, um benutzerdefinierte Annotationen in das Schema aufzunehmen:

Parameter

  • Name: classAnnotation
    • Typ: Doctrine\Common\Annotations\Annotation
  • Name: settings
    • Typ: Array
    • Bisherige Schema-Eigenschaften der Entität, wird wieder zurückgeschrieben (muss dafür im Eventhandler mit $event->setProperty('settings', $settings) gesetzt werden)

pim.schema.after.propertyAnnotation
Wird aufgerufen, nachdem eine Property-Annotation verarbeitet wurde. Kann genutzt werden, um benutzerdefinierte Annotationen in das Schema aufzunehmen:

Parameter

  • Name: propertyAnnotation
    • Typ: Doctrine\Common\Annotations\Annotation
  • Name: properties
    • Typ: Array
    • Bisherige benutzerdefinierte Schema-Eigenschaften zur Property, wird wieder zurückgeschrieben (muss dafür im Eventhandler mit $event->setProperty('properties', $properties) gesetzt werden)

Symlinks zur Laufzeit überprüfen

Beim Upload des APP-CMS per FTP werden teilweise die Symlinks falsch übertragen. Daher ist eine Überprüfung und Erstellung zur Laufzeit sinnvoll, da sonst das APP-CMS nicht lauffähig ist.

Fehler bei api/query und Permission=OWN

An exception occurred while executing 'SELECT * FROM TABLE WHERE userCreated = ? OR FIND_IN_SET(?, users) = 1' with params [{}]:\n\nSQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

Z.B. Zeile classes/api.php 1252ff.:

$queryBuilder->andWhere("$entityAlias.userCreated = ? OR FIND_IN_SET(?, $entityAlias.users) = 1");
$queryBuildr->setParameter($paramCount, $this->app['auth.user']);
$paramCount++;

in

$queryBuilder->andWhere("$entityAlias.usercreated_id = ? OR FIND_IN_SET(?, $entityAlias.users) = 1");
$queryBuilder->setParameter($paramCount, $this->app['auth.user']->getId());
$paramCount++;
$queryBuildr->setParameter($paramCount, $this->app['auth.user']->getId());
$paramCount++;

Modul-Unterstützung

Aufteilung (oder als zusätzliche Option) des custom-Ordners in Modulen, um bei größeren Projekten die Übersichtlichkeit zu bewahren.

  • custom
  • modules
    ** modul1
    ** modul2
    ** ...

Jedes Modul besitzt dabei den gleichen/ähnlichen Aufbau/Logik wie der custom-Ordner, plus zusätzlich einer Installationsroutine, um z.B. assets-Ordner freizugeben (Symlink in public-Ordner).

One2One-Joins

Anzeige und Speicherung von One2One-Joins funktioniert nicht richtig.

  • Felder wie Besitzer, etc. ausblenden
  • Besitzer, etc. automatisch setzen

Datenexport als Excel/CSV/XML

Automatischer Datenexport einer Entität/Liste/Report (inklusive Beachtung der Filter) als Excel, CSV und/oder XML. Download über Dropdown-Button z.B. neben Filter-Button

Benutzerdefinierte Berichte/Listen

  • Definition der Abfrage auf Basis api/query - kann vom Administrator im Backend in Entität "PIM\Reports" erstellt werden
    • Name des Berichts
    • Abfrage
    • Button/s + Aktion (z.B. Öffnen von Edit-Formular)
  • Auflistungen aller Reports für Benutzer
  • Liste und Filter wird automatisch generiert - Anzeige wie bisherige Entitäten-Auflistungen

Erweiterung Authentifizierung um LoginManager

Erweiterung um die Authentifizierung auch gegen Drittsysteme (z.B. ERP) durchzuführen.

API-Methode auth/login um zusätzlichen, optionalen Parameter "loginManager" ergänzen
Wenn dieser gesetzt ist, die entsprechende loginManager-Klasse laden.
loginManager->auth() aufrufen und entsprechenden User zurückgeben

Der User muss in der benutzerdefinierten loginManager-Klasse entsprechend gesetzt werden. Beispielsweise durch Überprüfen von Benutzername und Passwort per Curl gegen ein Drittsystem und Erstellen eines Benutzer im System.

API: /auth/login

{
  loginProvider: 'ERPLoginProvider',
  user: 'username',
  pass: 'pass'
}

Custom/Classes/ERPLoginProvider.php

 namespace Custom\Classes;

    namespace Custom\Classes;
    use Areanet\PIM\Classes\Manager\LoginManager;
    class ERPLoginProvider extends LoginManager
    {
    public function auth(){
        $username = $this->request->get('user');
        $password = $this->request->get('pass');
        if(!$this->erpAuth($username, $password)){
            throw new Exception('Authentifizeriung fehlgeschlagen.');
        }
        return $this->createManagedUser($username);
    }

    protected function erpAuth(){
        //Prüfe gegen ERP-Drittsystem per Curl
        return true;
    }
 }

Zweiter Anzeigemodus in Liste und Formular

Konfigurierbar über Entity-Klassen-Annotation:
`/**

  • @Orm\Entity
  • @Orm\Table(name="produkt")
  • @pim\Config(label="Produkt", viewMode=1")
    */`

viewMode = 0
Standard wie bisher

viewMode = 1
In der Liste wird der Löschen-Button nicht dargestellt, dafür ein Anzeige-Button, mit dem das Objekt lesend geöffnet/angezeigt werden kann.
Der Löschen-Button wird dafür im Bearbeitungsformular links unten angezeigt.

API-Aufrufe auslagern

API-Aufrufe vom ApiController in API-Klasse auslagern (siehe singleAction), um innerhalb eigener Programmierung direkt auf die API zugreifen zu können.

HTTP-Authentifizierung für CGI

Anpassung der .htaccess und der index.php, um die HTTP-Authentifizierung auch für PHP als CGI-Modul aktivieren zu können.

Push-Notifications aus Core entfernen

  • Nicht mehr an Entität binden
  • Eigene Klasse, bzw. Silex-Service $app['push]->send() für mehr Flexibilität
  • Native Push über Firebase Cloud Messaging (Android / iOS)
    • Channel-Unterstützung
    • benutzerdefiniert für Apple Push-Service erweiterar/optional
  • Webpush / Browser-Notifications

Cronjob-Manager

Implementierung eines Cronjob-Managers. Aufruf eines einzigen Cronjobs, über z.B.

console.php appcms:cronjobs --run

Registrierung von beliebigen Befehlen/"Sub-Cronjobs", die über das Backend verwaltet werden können:

  • Aktivieren/Deaktivieren
  • Intervall (alle 5 Minuten, alle 30 Minuten, jede Stunde,...)

Vergleiche Shopware Cronjobs:
https://community.shopware.com/Cronjobs_detail_1102.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.