Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Chameleon Base Laravel Package

chameleon-system/chameleon-base

Core foundation package for the Chameleon System PHP CMS, providing shared base classes, bootstrap and configuration helpers, service utilities, and common components used by Chameleon modules and extensions. It streamlines setup and extension development for Chameleon-based applications.

View on GitHub
Deep Wiki
Context7

Getting Started

chameleon-system/chameleon-base is the technical foundation of the Chameleon CMS — the container bootstrapping, the table/record abstraction, the module system, and the shared services that every other Chameleon package builds on. You almost never install it "bare"; you install it as the base of a project and let the other chameleon-system/* packages (core, backend, standard modules) layer on top.

Minimal steps:

  1. Check compatibility before you invest. Last tagged release is December 2018, which puts it in the PHP 7.0–7.2 / Symfony 3.x era. Confirm PHP version in composer.json and require constraints first — this is the single biggest decision point.
  2. composer require chameleon-system/chameleon-base in a project skeleton, or clone an existing Chameleon project and treat this as a vendor dependency you read, not edit.
  3. Provision MySQL, import the shipped schema/seed dump, and point the app at it via the project's config directory (Chameleon traditionally keeps a per-customer config layer separate from vendor code — find that directory, it's where DB credentials and environment flags live).
  4. Boot the app and log into /cms (backend). If the login page renders, the container, DB connection, and autoloading are all healthy — that's your smoke test.
  5. First real use case: create one table and one module in the backend, then render it on the frontend. That single loop touches the schema manager, the record layer, the module system, and the view renderer — i.e. everything this package provides.

Where to look first, in order: composer.json (dependency shape and PHP floor), the bundle/service wiring under src/, the auto-generated record classes (they tell you the naming conventions faster than any doc), and the backend module registry.

Implementation Patterns

The record layer is the API. Chameleon generates a class per database table (TdbCms* / Tdb<Customer>*) at runtime/build time, all extending the base record class. Day-to-day work looks like:

$page = TdbCmsPage::GetNewInstance();
$page->LoadFromField('id', $pageId);

$list = TdbCmsPage::GetList();
$list->AddWhereToQuery("`cms_page`.`active` = '1'");
$list->SetOrderBy('name');
foreach ($list as $record) { /* ... */ }

Use the generated classes and record lists rather than hand-written SQL — they carry field metadata, localization handling, and caching. Drop to raw SQL only for reporting/aggregation where the record overhead is genuinely wasteful, and then still use the DBAL connection from the container rather than a global handle.

Backend CRUD goes through the table editor manager, not the record. For anything that must behave like a native backend edit (field types, permissions, workflow, history), drive TCMSTableEditorManager rather than saving records directly:

$editor = new TCMSTableEditorManager($db, $tableId);
$editor->SetId($recordId);
$editor->SaveField('name', $value);

Direct Save() on a record bypasses validation and the audit trail — fine for imports, dangerous for user-facing writes.

Modules are the unit of backend functionality. A backend module is a PHP class (implementing the module contract) plus a DB row describing it: name, icon, permission, and the class to instantiate. The pattern is: register the module → implement Execute() → return a rendered view. Keep module classes thin; push logic into a service.

Views are plain .view.php templates rendered by the framework's view object ($oView in template scope). Business logic belongs in the module or a service; templates should only read prepared data. Use the framework's escaping helpers — the frontend layer does not auto-escape.

Wire new code through the service container. Register services in a project bundle's services.yml and inject them; avoid TGlobal::Get()-style lookups in new code. This is the one area where you can write modern code on an old foundation, and it pays off in testability.

Extend by overriding, not patching. Chameleon supports replacing core services/classes via the container and via class-extension points. For a customized table or module, subclass the generated record or the module and point the config at your subclass. Never edit generated classes or vendor files — they are regenerated.

Schema changes belong in the project's migration/update mechanism, not ad-hoc ALTER TABLE. Chameleon tracks the data model and regenerates classes from it; an out-of-band column will exist in MySQL but not in the ORM until you resync and clear caches. Treat "edit field in backend → regenerate → clear cache" as one atomic step.

Gotchas and Tips

  • The 2018 date is the headline risk. Expect friction on PHP 8 (each(), create_function, dynamic properties, curly-brace string offsets, Symfony 3/4 deprecations). Budget for either pinning an old PHP runtime (with the security implications that carries) or a real upgrade effort before you commit.
  • Cache clearing is not optional. After schema changes, module changes, or service wiring changes, clear the Chameleon caches (framework cache + generated-class cache). "My field/class doesn't exist" is almost always a stale cache, not a bug.
  • Do not edit generated record classes. They are rebuilt from the data model. Your changes vanish — and worse, they vanish silently on the next regeneration. Subclass or use the extension hooks.
  • Two config layers. Vendor defaults plus the project/customer config. Know which one you're editing; changes in the wrong layer get overwritten on update. Environment-specific values belong in the project layer.
  • Record objects are heavy. Loading thousands of full records to read one field is a classic performance trap. Use record lists with explicit field selection, and reuse loaded records within a request.
  • Field naming and prefixes are load-bearing. The cms_ prefix, table-to-class mapping, and localization field suffixes are conventions the framework relies on. Renaming a table outside the tooling breaks class generation.
  • Permissions are enforced in the module layer. A module with no permission row behaves unpredictably in the backend; give every module an explicit right and verify with a non-admin user.
  • Debugging: use the Symfony profiler/logs for container and DB issues; for record-layer issues, log the generated SQL from the record list — most "wrong data" reports are a missing AddWhereToQuery or an order-by applied to the wrong list instance.
  • Escape at output, always. The template layer is permissive; assume nothing is escaped for you. This is the most likely source of XSS in a Chameleon build.
  • Extension points worth knowing: service overrides in the container, record/module subclassing, and the framework's event/hook mechanism. Prefer these three in that order; they survive updates, patches don't.
  • Testing: the framework's static/global accessors make unit testing painful. Keep new logic in injected services with no container lookups and you can test it normally; test the module classes through the backend instead.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager