summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md258
1 files changed, 251 insertions, 7 deletions
diff --git a/README.md b/README.md
index 4913ab1..9ed201b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,251 @@
-Having been using bitweaver for many years I have now retired from buisness and am
-carrying on things for enjoyment, not that maintaining PHP is a joy at times.
-I have several sites that have been live on bitweaver under PHP7.3 from their creating
-and now I have moved them to a more modern webstack under PHP8.4 with Firebird5.
-This form of the code is a little of a tangent from the main code base as I have also
-hacking into Smarty5 and andded namespace to the mix. It's published here in the hope
-someone might find parts of it useful.
+# bitweaver-lsces
+
+A personal fork of [bitweaver](http://www.bitweaver.org/) — a PHP CMS and application framework
+originally derived from TikiWiki. This organisation holds one repository per package. All packages
+are deployed together under a single web root (`bitweaver5/`).
+
+Having used bitweaver for many years across several live sites, this fork has been carried forward
+into a modern stack: PHP 8.5, Firebird 5, Smarty 5 with namespaces, and adodb on a custom branch.
+It is published here in the hope that parts of it are useful to others.
+
+---
+
+## Stack
+
+| Layer | Technology |
+|---|---|
+| Language | PHP 8.5 |
+| Database | Firebird 5 via adodb (`v5.22.11-lsc` branch) |
+| Templates | Smarty 5 |
+| CSS/JS | Bootstrap 3, jQuery — no npm, no Node.js |
+| Web server | nginx + php-fpm |
+
+---
+
+## Architecture Overview
+
+Bitweaver is built around a **package system**. Every feature area (articles, blogs, contact,
+stock, etc.) is a self-contained directory under the web root. Packages are loosely coupled
+through a small set of global objects and a shared database.
+
+### Packages
+
+Each package directory follows this layout:
+
+```
+<package>/
+ admin/ package administration pages
+ includes/
+ bit_setup_inc.php package self-registration (always loaded)
+ classes/ PHP classes for this package
+ config_defaults_inc.php package-level config defaults (optional)
+ templates/ Smarty templates (.tpl)
+ modules/ sidebar/layout module templates
+ index.php package landing page
+ *.php entry-point pages (list, edit, view, add…)
+```
+
+`bit_setup_inc.php` is the only file loaded unconditionally for every request. It calls
+`$gBitSystem->registerPackage()` to declare the package and `$gBitSystem->registerAppMenu()`
+to add a navbar dropdown.
+
+### Request Lifecycle
+
+1. `index.php` (web root) → `kernel/includes/setup_inc.php`
+2. `setup_inc.php` initialises global objects (`$gBitDb`, `$gBitSystem`, `$gBitSmarty`,
+ `$gBitUser`), detoxifies `$_GET`, and loads `bit_setup_inc.php` for every active package.
+3. The requested page file runs: loads a content object, does DB work, assigns Smarty
+ variables, calls `$gBitSmarty->display( 'bitpackage:pkg/template.tpl' )`.
+4. Smarty renders through `kernel/templates/html.tpl` → layout columns → modules → page body.
+
+---
+
+## Class Hierarchy
+
+```
+BitBase (kernel — abstract, DB-aware base)
+└── LibertyBase (liberty — adds mContentId, mContentTypeGuid)
+ └── LibertyContent (liberty — full content lifecycle: store, load, expunge)
+ └── <Package class> e.g. Contact, StockAssembly, StockComponent, StockMovement
+```
+
+Additional kernel classes (not in the content hierarchy):
+
+- **`BitSystem`** (`$gBitSystem`) — package registry, config store, menu registration,
+ layout, error handling.
+- **`BitDbAdodb`** (`$gBitDb`) — thin adodb wrapper; all DB access goes through this.
+- **`BitSingleton`** — base for objects that must exist once (BitSystem inherits from this).
+- **`KernelTools`** — static utility methods: `tra()` (translation), `detoxify()`, etc.
+- **`RolePermUser`** (`$gBitUser`) — the logged-in user; holds roles, permissions, preferences.
+
+---
+
+## Key Globals
+
+| Variable | Class | Purpose |
+|---|---|---|
+| `$gBitDb` | `BitDbAdodb` | Database connection |
+| `$gBitSystem` | `BitSystem` | Package registry, config, menus |
+| `$gBitSmarty` | Smarty subclass | Template engine |
+| `$gBitUser` | `RolePermUser` | Current user (anonymous or authenticated) |
+| `$gContent` | `LibertyContent` subclass | The content object for the current page |
+
+---
+
+## Database Layer
+
+All queries use **adodb** — no raw PDO or mysqli. The wrapper is `BitDbAdodb` in
+`kernel/includes/classes/BitDbAdodb.php`.
+
+Key adodb methods used throughout the codebase:
+
+| Method | Purpose |
+|---|---|
+| `getArray($sql, $vals)` | Returns all rows as a numerically-indexed array |
+| `getAssoc($sql, $vals)` | Returns rows keyed by the first column |
+| `getOne($sql, $vals)` | Returns a single scalar value |
+| `getRow($sql, $vals)` | Returns a single row as an associative array |
+| `query($sql, $vals)` | Execute; returns a recordset (iterate with `fetchRow()`) |
+| `executeQuery($sql, $vals, $numrows, $offset)` | Paginated query |
+
+Placeholders are always positional `?`. Named binds are not used.
+
+The database is **Firebird 5**. Firebird is stricter than MySQL in several ways that matter:
+- Every non-aggregate `SELECT` column must appear in `GROUP BY`.
+- `IN ()` with an empty list is a syntax error — always guard with a fallback.
+- `FIRST n` / `ROWS n` for limiting result sets (not `LIMIT`).
+- `LOCALTIMESTAMP` / `CURRENT_TIMESTAMP` as default expressions behave differently from MySQL.
+
+---
+
+## Template System (Smarty)
+
+Templates live in `<package>/templates/`. The `bitpackage:` Smarty resource prefix resolves
+templates through a search path that allows per-site overrides:
+
+1. `config/themes/<site>/` (symlink to `/etc/webstack/domains/<site>/themes/<site>/`)
+2. `<package>/templates/`
+
+This means dropping a template file into the site-specific path silently overrides the
+package default — useful for site-specific customisation without forking the package.
+
+**Important Smarty conventions in this codebase:**
+
+- `{tr}...{/tr}` for user-visible strings (maps to `KernelTools::tra()`).
+ `"string"|tra` is **not** a valid Smarty modifier and will throw a compiler error.
+- `{form}...{/form}` block plugin auto-injects the CSRF ticket hidden field.
+- `{strip}` removes inter-tag whitespace; keep content like `&bull;` inside valid elements.
+- Per-site footer scripts go in `kernel/footer_inc.tpl`, not `kernel/footer.tpl`.
+ `footer_inc.tpl` is loaded via the `mAuxFiles` loop in `html.tpl` and is reliable.
+ `footer.tpl` as a theme override only loads when the active style name matches exactly.
+
+---
+
+## Permission / Role System
+
+Roles are stored in the `users_roles` table. Default role IDs:
+
+| role_id | Name | perm_level |
+|---|---|---|
+| 1 | Administrators | admin |
+| 2 | Editors | editors |
+| 3 | Registered | registered |
+| -1 | Anonymous | basic |
+
+Permissions are declared in `<package>/admin/schema_inc.php` and stored in
+`users_role_permissions`. `$gBitUser->hasPermission('p_pkg_action')` is the standard check.
+
+When writing role-filter queries, guard the `IN()` list with:
+```php
+array_keys($gBitUser->mRoles ?? []) ?: [-1]
+```
+Firebird rejects `IN ()` with an empty list.
+
+---
+
+## Liberty Content System
+
+The **liberty** package is the content engine. All content types (pages, articles, contacts,
+stock items, movements, …) share a single `liberty_content` table row identified by a
+`content_id` and a `content_type_guid` string.
+
+A package registers its content type in `schema_inc.php` and provides a class that extends
+`LibertyContent`. The class overrides `store()`, `load()`, and `expunge()` to handle its
+own additional tables/xrefs on top of the base liberty row.
+
+### XRef System
+
+`liberty_xref` is a flexible key-value extension table attached to any content item.
+Rows are grouped by `x_group` and typed by `item`. The OOP layer wraps this:
+
+- **`LibertyXrefType`** — describes one xref slot (group, item key, cardinality, etc.)
+- **`LibertyXref`** — one populated xref row
+- **`LibertyXrefGroup`** — a collection of xref rows sharing an `x_group`
+- **`LibertyXrefInfo`** — the full set of xref groups for a content item
+
+**Loading pattern** (display and edit pages):
+```php
+$gContent->loadXrefInfo();
+$gBitSmarty->assign('gXrefInfo', $gContent->mXrefInfo);
+```
+
+**Template pattern**:
+```smarty
+{foreach $gXrefInfo->mGroups as $xrefGroup}
+ {include file=$gContent->getXrefListTemplate($xrefGroup->mTemplate)
+ xrefGroup=$xrefGroup allow_edit=false}
+{/foreach}
+```
+
+Group templates receive `$xrefGroup` (a `LibertyXrefGroup` object). The first two lines
+of every group template set local flags:
+```smarty
+{assign var=xrefAllowEdit value=$allow_edit|default:false}
+{assign var=isHistory value=($xrefGroup->mXGroup eq 'history')}
+```
+
+---
+
+## Session / Authentication
+
+Cookie name: `bit-user-{site_title_stripped}` (lowercase alphanumeric).
+
+Login stores the PHP `session_id()` in `users_cnxn.cookie` mapped to `user_id`. Subsequent
+requests look up the cookie value in `users_cnxn` to identify the user. This is independent
+of PHP's own session mechanism even though they share the same cookie name.
+
+---
+
+## Deploy Path
+
+Code is developed and tested live in `/srv/website/bitweaver5/` (with xdebug available).
+Proven changes are copied to the matching package repo under `~/Development/bitweaver-lsces/<pkg>/`,
+reviewed with BeyondCompare, then committed and pushed.
+
+Servers (`srv9`, `srv10`) pull from the desktop's local git repos — **not** from GitHub.
+The deploy script is `/etc/webstack/scripts/server-pull-all.sh <package>`.
+
+Test on **srv9** first. `srv10` is production and only receives changes proven on srv9.
+
+After any deploy that touches Smarty templates: clear the template cache and restart php-fpm.
+
+---
+
+## Packages in This Organisation
+
+| Package | Content type | Notes |
+|---|---|---|
+| kernel | — | Bootstrap, globals, BitSystem, BitBase |
+| liberty | `liberty_content` | Content engine, xref system |
+| users | — | Auth, roles, permissions |
+| themes | — | Layout, CSS loading, module system |
+| languages | — | Translations, `tra()` string lookup |
+| config | — | Site-level overrides (CSS, templates) |
+| contact | `contact` | Person and business contacts, CSV import |
+| stock | `stockassembly`, `stockcomponent`, `stockmovement` | BOM, stock levels, movement CSV import |
+| articles | `article` | — |
+| blogs | `blog`, `blogpost` | — |
+| wiki | `wiki page` | — |
+| fisheye | `fisheye` | Image gallery |
+| messages | — | Internal messaging |
+| util | — | Shared JavaScript, icons, cross-package utilities |