CoreInto is a set of PHP files and one MySQL or MariaDB database. You upload the files to a hosting account, create an empty database, open the web installer in a browser, and add one cron job. This chapter takes you from an empty hosting account to a working admin area: the requirements, the installer, the configuration file, the storage folder, the cron job, the address style, the first sign-in and two-step sign-in for staff, what to back up, and a short tour of where things are in the admin area.
Requirements
The installer checks these before it lets you install. The same checks are in app/src/Installer.php.
| Requirement | Needed or recommended | Why |
|---|---|---|
| PHP 8.1 to 8.5 | Needed | CoreInto refuses to start on older PHP. The installer shows the version it found. |
PDO with MySQL (pdo_mysql) | Needed | The database connection. |
OpenSSL (openssl) with AES-256-GCM | Needed | Encrypts stored secrets (server passwords, gateway keys, two-step seeds). |
Multibyte strings (mbstring) | Needed | Text handling. |
JSON (json) | Needed | Settings, module settings and the API. |
cURL (curl) | Recommended | Payment gateways, registrars, Google reCAPTCHA, the update check. |
GD (gd) | Recommended | Images. |
Intl (intl) | Recommended | Languages and international domain names. |
Zip (zip) | Recommended | Installing updates from the Update CoreInto page. |
The storage folder can be written to | Needed | Attachments, files, logs, backups and cache live there. |
The database must be MySQL 5.7 or newer, or MariaDB 10.3 or newer, with InnoDB. CoreInto has been tested on PHP 8.3 and MariaDB 10.11; it has not yet been tried on PHP 8.1, MySQL 5.7 or MySQL 8.
CoreInto needs no shell access, no Composer and no outside libraries. It runs on an ordinary shared hosting account.
Uploading the files
- Upload every file and folder to the folder the site will use, for example
public_html(the site athttps://billing.example.com) orpublic_html/billing(the site athttps://www.example.com/billing). - In your hosting control panel, create an empty MySQL or MariaDB database and a database user with all rights on it. Note the database name, user and password.
- Make sure the web server can write to the
storagefolder.
The top folder holds these entry points:
| File or folder | What it is |
|---|---|
index.php | Public pages and the client area |
admin/index.php | The admin area (the folder can be renamed, see below) |
api/index.php | The JSON API, see API |
install/index.php | The web installer; delete the folder after installing |
cron.php | The automation, run by a cron job |
cli.php | Commands for the server's command line, see Command line |
app/ | CoreInto's code, closed to the web |
assets/ | Stylesheets, scripts and the logo |
storage/ | Data files, closed to the web |
.htaccess | Rules for Apache and LiteSpeed (see "Address style") |
The web installer
Open https://your-site/install/ in a browser. The page shows the server check first: each requirement with a tick or a cross, and "(recommended)" after the optional ones. If a needed item is missing, the form is shown but installing is refused with "This server does not meet the requirements listed above."
Fill in the form:
Database
| Field | What to enter |
|---|---|
| Database host | Usually localhost. |
| Port | Usually 3306. |
| Database name | The empty database you created. |
| Database user | The user with all rights on it. |
| Database password | Its password. |
Your company
| Field | What to enter |
|---|---|
| Address of this CoreInto | Where clients will open it, for example https://billing.example.com. The installer guesses it from the address you opened; it must be the full address with https:// or http://. |
| Company name | Used as the company name, the sender name of emails and in the email signature. |
| Company email address | Shown to clients and used as the sender address of emails. |
| Country (two-letter code) | For example GB, US or PK. Becomes the default country for new clients. Optional. |
| Main currency | A three-letter code such as USD, EUR, GBP or PKR. The starting currency is renamed to this code and given its sign. |
| Time zone | For example Europe/London or Asia/Karachi. Due dates, the daily automation run and reports follow this zone. UTC when left empty. |
First administrator
| Field | What to enter |
|---|---|
| Username | 2 to 64 letters, digits, dots, dashes or underscores. The default is admin. |
| Email address | The administrator's email address. |
| Password, Password again | At least 10 characters with a strength score of 50 or more: mix letters, digits and symbols. |
Licence
| Field | What to enter |
|---|---|
| CoreInto licence key | The key from the service page of your CoreInto licence (CI-...). It is checked with the licence server at the end. It can be left empty and entered later. |
Press Install. The installer then:
- Connects to the database and refuses if it already holds a CoreInto installation with staff in it ("Use an empty database").
- Creates every table and the seed data (the numbered files in
app/migrations/). - Creates the three standard administrator roles: Full Administrator, Sales Operator and Support Operator.
- Saves your company name, email, country, time zone and currency as settings, and makes a random cron key.
- Tests whether short addresses reach
index.php(see "Address style") and saves the result. - Creates the first administrator with the Full Administrator role.
- Checks the licence key with the licence server and saves it with the answer.
- Writes
configuration.phpinto CoreInto's top folder, next toindex.php.
The finished page says whether the key was accepted. Until a key is accepted the admin area opens only Utilities > CoreInto Licence (see CoreInto licence); the client area works from the start.
The "CoreInto is installed" page lists three things to do now:
- Delete the
installfolder. Whileconfiguration.phpexists the installer is closed anyway, but the folder should not stay on a live site. - Add a cron job that runs every 5 minutes. The exact command for your server is shown on the page.
- Back up
configuration.php. It holds the encryption key.
If the installer could not write configuration.php (the folder is not writable), the page shows the full text of the file in a box. Create the file yourself in CoreInto's top folder with exactly that content, then open the admin area.
The page also says which address style was chosen: either "short addresses work on this server" or that addresses will look like index.php?r=/page, which can be changed later under Settings > General Settings.
The configuration file
configuration.php is the only file that holds settings outside the database. Everything else is a setting in the database (see Settings). The file is a PHP file that returns an array:
<?php
// CoreInto configuration. Keep a copy of encryption_key with your backups:
// without it, stored passwords and keys cannot be read.
return [
'db_host' => 'localhost',
'db_port' => 3306,
'db_socket' => '',
'db_name' => 'example_billing',
'db_user' => 'example_billing',
'db_pass' => 'secret',
'encryption_key' => 'base64 text of 32 random bytes',
'system_url' => 'https://billing.example.com',
];
Every key CoreInto reads (app/src/Config.php):
| Key | What it does |
|---|---|
db_host | Database server. Default localhost. |
db_port | Database port. Default 3306. |
db_socket | A Unix socket path instead of host and port. Empty by default. |
db_name | Database name. Required. |
db_user | Database user. Required. |
db_pass | Database password. |
encryption_key | 32 random bytes as base64 text. Every secret stored in the database is encrypted with it. The installer makes it. If it is lost or changed, the stored secrets cannot be read. |
system_url | The full address of CoreInto with no trailing slash, for example https://billing.example.com. Used in emails and in links that leave the site. |
storage_path | Where the data files are kept. Default: the storage folder in CoreInto's top folder. The installer does not write this key; add it by hand if you move the folder. |
trusted_proxies | A list of addresses whose X-Forwarded-For and X-Forwarded-Proto headers are believed, for sites behind a reverse proxy. Default ['127.0.0.1', '::1']. Add your proxy's address here if visitors' addresses show as the proxy's address in the logs. |
Where CoreInto looks for the file, in this order:
- The file named by the
COREINTO_CONFIGenvironment variable, if that variable is set. coreinto-configuration.phpone folder above CoreInto's top folder (outside the web root, which is the safer place).configuration.phpin CoreInto's top folder.
The installer writes to the path in COREINTO_CONFIG when it is set, otherwise to configuration.php in the top folder. To move the file above the web root after installing, move it to ../coreinto-configuration.php and delete the copy in the top folder. .htaccess refuses to serve configuration.php to browsers on Apache and LiteSpeed.
When the file is missing, every page redirects to /install/.
The storage folder
storage/ holds everything CoreInto writes to disk. It is closed to the web by its own .htaccess ("Require all denied") and by the rule in the top .htaccess. The web server user must be able to write to it and to its subfolders.
| Folder | Holds |
|---|---|
storage/attachments/tickets | Ticket attachments |
storage/attachments/pdf | PDF copies of invoices attached to emails, kept 90 days |
storage/files | Client files, under random names |
storage/downloads | Files offered under Support > Downloads |
storage/backups | Database backups (Settings > Database Backups) |
storage/cache | Temporary data, such as registrar domain lists being read |
storage/updates | Zips of the files replaced by an installed update |
storage/logs | error-YYYY-MM.log, one file per month, with any PHP errors |
If a page fails with "Something went wrong on our side", look in storage/logs/error-YYYY-MM.log for the reason.
The cron job
The automation (invoices, reminders, suspensions, domain sync, email sending and so on) runs from cron.php. Add a cron job in your hosting control panel that runs every 5 minutes:
*/5 * * * * php -q /home/USER/public_html/cron.php
Use the full path to cron.php on your server. The exact command is shown on the installer's last page and under Utilities > Automation Status. Add -v to the command to see what ran when you try it by hand:
php -q /home/USER/public_html/cron.php -v
Daily tasks run once a day at the hour set under Settings > Automation Settings, Schedule tab ("Hour of the daily run", default 9) in the company's time zone. Other tasks run every few minutes or hours. Automation lists every task.
Web cron. If your host only offers web cron jobs (a URL fetched on a schedule), use this address instead:
https://billing.example.com/cron.php?key=CRONKEY
The key is made at installation and shown under Utilities > Automation Status, in the "The cron job" box. Keep the address private; without the right key the page answers "Forbidden". Both ways do the same work, and both wait while a database update is pending (see "Updating").
The dashboard's Automation Overview widget shows the time of the last daily run and warns when the daily automation has not run for 26 hours. Utilities > Automation Status warns when the last cron run was more than 2 hours ago.
Address style
CoreInto can show its addresses in two styles. The setting is RouteMode under Settings > General Settings, General tab, "Address style":
| Choice | Addresses look like | Works where |
|---|---|---|
index.php?r=/page (works everywhere) ("basic") | https://billing.example.com/index.php?r=/client/invoices | Every web server. |
Short addresses: /page ("rewrite") | https://billing.example.com/client/invoices | Servers that pass unknown addresses to index.php. The .htaccess file does this on Apache and LiteSpeed. |
The installer tests the server itself: it fetches SITE/__ci_rewrite_test and chooses "rewrite" when index.php answers. If you later move to a server that honours .htaccess, change the setting. If short addresses stop working after a server change, set it back to basic.
The .htaccess files also:
- refuse to serve
configuration.php,cli.php,.sql,.log,.mdand.bakfiles, and files starting with a dot; - refuse direct access to
app,storage,tests,docsandtools; - send
/api/v1/ACTIONtoapi/index.php; - turn off directory listings.
nginx. CoreInto ships no nginx configuration. On nginx, use the basic address style, or write your own rules that pass unknown addresses to index.php, send /api/v1/ to api/index.php, and refuse the files and folders listed above. The JSON API also accepts api/index.php?action=ACTION where /api/v1/ACTION cannot be rewritten.
Renaming the admin folder
The admin area lives in the admin folder and is reached at https://billing.example.com/admin/. You may rename the folder, for example to office; the admin area finds its own name from the address it is opened at.
Links from the client area and from emails to the admin area are built from the setting AdminDir. This setting has no field on any settings page. After renaming the folder, set it in the database so those links point to the new name:
INSERT INTO settings (name, value) VALUES ('AdminDir', 'office')
ON DUPLICATE KEY UPDATE value = 'office';
Without it, links to the admin area in staff emails and in the client area still say /admin/.
First sign-in
Delete the install folder first: while it is still on the server, the admin sign-in page refuses every sign-in and says so, because the folder would let anyone reinstall CoreInto. The same rule applies after an update that puts the folder back. Then open https://billing.example.com/admin/ and sign in with the username and password you gave the installer. The sign-in page also offers "Forgotten your password?" while the setting "Staff may reset a forgotten password by email" is on; the link is emailed to the administrator's address and works for 60 minutes.
After five failed sign-ins from one address (setting "Failed sign-ins before a ban", default 5) the address is banned for 15 minutes (setting "Minutes an address is banned after failed sign-ins", default 15) and listed under Settings > Banned IPs. Addresses on the "Addresses never banned" list still wait out the lock-out but are not added to Banned IPs. See Staff and security.
An administrator created from the command line, or marked "Ask for a new password at the next sign-in", is sent to My Account to choose a new password before any other page opens.
Two-step sign-in for staff
Each administrator turns two-step sign-in on for themselves under My Account (the user menu at the top right): press Set Up, enter the current password, scan the QR code with an authenticator app (Google Authenticator, Microsoft Authenticator, Authy, 1Password and the like) or type the key shown, and enter the 6-digit code from the app. CoreInto then shows eight one-time recovery codes. Save them: they are not shown again, and each works once when the phone is lost.
From then on, after the password the sign-in asks for the 6-digit code or a recovery code. Five wrong codes end the attempt and count as a failed sign-in.
To make two-step sign-in compulsory for every administrator, tick "Require two-step sign-in for all staff" under Settings > Two-Step Sign-In. Anyone without it is sent to My Account to set it up before other pages open, and cannot turn it off. The same page lists which administrators have it set up and lets staff with the Administrators permission turn it off for someone who lost both phone and recovery codes.
The encryption key and what to back up
Secrets in the database are encrypted with the encryption_key in configuration.php: server passwords and tokens, gateway and registrar keys, saved card references, domain transfer codes, service passwords, two-step seeds, SMTP and reCAPTCHA secrets, department mailbox passwords and encrypted custom fields. A database dump alone reveals none of them, and without the key none of them can be read back.
Back up:
- The database. Settings > Database Backups makes a gzip SQL dump into
storage/backupson demand and daily (taskbackup, kept for the number of days set under Settings > Automation Settings, Data retention tab; the newest is always kept). Download the files from that page or copy them from the folder. Your control panel's backup or phpMyAdmin "Export" work too. configuration.php(orcoreinto-configuration.php). It holds the encryption key. Keep a copy with every database backup.- The
storagefolder: attachments, client files, downloads and backups.
To restore, import the dump into an empty database, put the files and the storage folder back, and put configuration.php back with the same encryption_key.
Updating
- Back up the database first.
- Either upload the new files over the old ones (the update zip has no
installfolder and never containsconfiguration.phpor anything instorage), or use Utilities > Update CoreInto, which downloads a signed release from the licence server, makes a database backup, keeps a copy of the replaced files instorage/updatesand writes the new files. That page needs a licence that is in order and PHP's zip extension. - Sign in to the admin area. If the new version changes the database, every page redirects to Database Update, which lists the changes waiting. Press "Update the Database" (needs the "Update CoreInto" permission). Until then the client area answers "This site is being updated" and
cron.phpwaits.
The version is shown on the dashboard under System Information. The daily task update-check asks the licence server for new versions.
Where things are: a tour of the admin area
The top bar has a "+" menu for the things staff add most (client, order, invoice, quote, ticket, to-do entry), the menus, a search box that shows results as you type (after three characters, grouped by kind; Enter opens the full search page), a bell with the counts of pending orders, tickets waiting, overdue invoices and pending module actions, the Settings gear, a light or dark theme switch, and the user menu with My Account, Visit Client Area and Sign out. Menu items a role may not use are hidden.
Every page has a sidebar on the left with the links of the page's menu (on settings pages, every settings page in its group), blocks that belong to the page (the client's tabs and holdings on a client page, the ticket's details and filters on ticket pages, the list of reports on report pages), a quick search that goes straight to the clients, services, domains, orders, invoices or tickets list, and the staff online. "Minimise sidebar" folds it away and the choice is remembered in the browser. At the bottom a dark footer shows the version with links to Automation Status and System Health.
Statuses have one colour throughout: green for active and paid, amber for pending and unpaid, red for overdue, open tickets and fraud, orange for suspended, blue for on hold, purple for refunded and collections, grey for cancelled, closed and draft, and slate for expired and terminated. Settings that are on or off are toggle switches. Actions that cannot be undone ask first in a pop-up, and short forms (adding a payment, a note, a status, a contact) open as pop-ups on the page they belong to. The pages are in English unless another interface language is installed and chosen (Settings > Languages; each staff member picks their own on My Account), see Languages.
Top menus
| Menu | Items |
|---|---|
| Clients | View/Search Clients, Manage Users, Add New Client, Products/Services (with Shared Hosting, Reseller Accounts, VPS/Servers, Other Services), Service Add-ons, Domain Registrations, Cancellation Requests, Manage Affiliates |
| Orders | List All Orders, Pending Orders, Active Orders, Fraud Orders, Cancelled Orders, Add New Order |
| Billing | Transactions List, Invoices (All, Paid, Draft, Unpaid, Overdue, Cancelled, Refunded, Collections, Payment Pending), Billable Items (All, Uninvoiced, Recurring, Add New), Quotes, Credit and Debit Notes, Disputes, Gateway Log |
| Support | Support Overview, Support Tickets (Flagged Tickets, All Active Tickets, Awaiting Reply, then one entry per ticket status), Open New Ticket, Predefined Replies, Announcements, Downloads, Knowledgebase, Network Issues |
| Reports | All Reports, Daily Performance, Income Forecast, Annual Income, New Customers, Ticket Feedback Scores, Batch Invoice PDF Export |
| Utilities | Automation Status, Email Marketer, Link Tracking, Calendar, To-Do List, WHOIS Lookup, Domain Resolver Checker, Integration Code, Import Data, Database Status, System Cleanup, System Health, Update CoreInto, Activity Log, Staff Sign-in Log, Module Log, API Log, Email Message Log, Ticket Mail Import Log, WHOIS Lookup Log |
| Add-ons | Licensing Manager, Licence Checks, Licensing Settings |
Each menu opens a panel with an icon per item; items with a sub-list (Invoices, Billable Items, Support Tickets) open it to the right on a desktop and as an indented list on a phone. Long menus such as Utilities are laid out in columns under headings so they fit on the screen. Below 900px wide the menus become a panel that slides in from the left. Tab strips on long pages (a client's tabs, a product's tabs) stay on one row: arrows at both ends scroll them when they do not fit.
The Settings index
The gear icon opens System Settings, a page of links in five groups. Links marked "Coming in a later update" lead to a page that says so; those parts are not built yet.
| Group | Pages |
|---|---|
| General | General Settings; Automation Settings; Storage Settings (not built yet); Marketing Consent (not built yet) |
| Payments | Currencies; Payment Gateways; Tax Configuration; Promotions |
| Products and Services | Products/Services; Configurable Options; Product Add-ons; Product Bundles; Domain Pricing; Domain Registrars; Servers |
| Support | Support Departments; Ticket Statuses; Escalation Rules; Spam Control |
| System | Administrators; Administrator Roles; Two-Step Sign-In; API Credentials; Email Templates; Custom Client Fields; Client Groups; Order Statuses; Fraud Protection (not built yet); Notifications (not built yet); Banned IPs; Banned Email Domains; Security Questions; Database Backups; Languages |
The dashboard
The dashboard is the admin home page. Which widgets a role MAY see is chosen under Settings > Administrator Roles, "Dashboard widgets"; some also need a permission. Within that, every staff member arranges their own dashboard: the gear button at the top right opens "Show/Hide Widgets" with a switch per widget and a "Reset layout" button; each widget has a drag handle (drag it to another place or the other column; the arrow keys work on the handle too), a collapse button and a hide button. The arrangement is saved for that staff member.
Sidebar:
| Block | Shows |
|---|---|
| Shortcuts (always) | New Client, New Order, New Invoice, New Quote, New Ticket, New To-Do Entry, WHOIS Lookup (those the role allows) |
| System Information | CoreInto version, PHP and database versions, who is signed in and their role |
| Staff Online | Administrators active in the last 15 minutes |
Main area, in the default arrangement:
| Widget | Shows |
|---|---|
| Tiles (widget "overview") | Pending Orders, Tickets Waiting, Overdue Invoices, Pending Cancellations, Pending Module Actions and Domains Expiring in 30 Days. Each links to its list. |
| System Overview | A chart of new orders, activated orders and money received, for Today by hour, the Last 30 days by day, or the Last year by month, with totals in the legend. The income series needs "See income totals". |
| Billing | Money received today, this month, this year and all time in the default currency, a bar for each of the last seven days, and the number of unpaid and overdue invoices. Needs "See income totals". |
| Support | Tickets awaiting a reply, tickets assigned to you, and the latest five tickets. |
| Automation Overview | When the cron job last ran (red after two hours), when the daily run last happened (red after 26 hours or never), how many tasks are failing, and what the last daily run did (invoices created, reminders sent, suspensions, terminations). |
| Client Activity | Active clients, users online in the last hour, and the latest eight client sign-ins with their address. |
| To-Do List | Up to eight open to-do items that are unassigned or assigned to you. Needs the "To-do list" permission. |
| Staff Online | Who is signed in to the admin area and when they were last seen. |
| Network Status | Your servers with their state, open network issues, and a link to add the first server when there is none. |
| System Health | Good, Fair or Poor with a meter: the cron age, failing tasks, module actions waiting, disk space and the PHP version, with a link to the System Health page. |
| Activity | The last ten lines of the activity log: date, user, description and IP address. Needs the "Activity log" permission. |
