CoreInto

Getting started

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.

CoreInto administrator guide: Getting started overview with the main sections of the article

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.

RequirementNeeded or recommendedWhy
PHP 8.1 to 8.5NeededCoreInto refuses to start on older PHP. The installer shows the version it found.
PDO with MySQL (pdo_mysql)NeededThe database connection.
OpenSSL (openssl) with AES-256-GCMNeededEncrypts stored secrets (server passwords, gateway keys, two-step seeds).
Multibyte strings (mbstring)NeededText handling.
JSON (json)NeededSettings, module settings and the API.
cURL (curl)RecommendedPayment gateways, registrars, Google reCAPTCHA, the update check.
GD (gd)RecommendedImages.
Intl (intl)RecommendedLanguages and international domain names.
Zip (zip)RecommendedInstalling updates from the Update CoreInto page.
The storage folder can be written toNeededAttachments, 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

  1. Upload every file and folder to the folder the site will use, for example public_html (the site at https://billing.example.com) or public_html/billing (the site at https://www.example.com/billing).
  2. 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.
  3. Make sure the web server can write to the storage folder.

The top folder holds these entry points:

File or folderWhat it is
index.phpPublic pages and the client area
admin/index.phpThe admin area (the folder can be renamed, see below)
api/index.phpThe JSON API, see API
install/index.phpThe web installer; delete the folder after installing
cron.phpThe automation, run by a cron job
cli.phpCommands 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
.htaccessRules 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

FieldWhat to enter
Database hostUsually localhost.
PortUsually 3306.
Database nameThe empty database you created.
Database userThe user with all rights on it.
Database passwordIts password.

Your company

FieldWhat to enter
Address of this CoreIntoWhere 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 nameUsed as the company name, the sender name of emails and in the email signature.
Company email addressShown 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 currencyA three-letter code such as USD, EUR, GBP or PKR. The starting currency is renamed to this code and given its sign.
Time zoneFor example Europe/London or Asia/Karachi. Due dates, the daily automation run and reports follow this zone. UTC when left empty.

First administrator

FieldWhat to enter
Username2 to 64 letters, digits, dots, dashes or underscores. The default is admin.
Email addressThe administrator's email address.
Password, Password againAt least 10 characters with a strength score of 50 or more: mix letters, digits and symbols.

Licence

FieldWhat to enter
CoreInto licence keyThe 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:

  1. Connects to the database and refuses if it already holds a CoreInto installation with staff in it ("Use an empty database").
  2. Creates every table and the seed data (the numbered files in app/migrations/).
  3. Creates the three standard administrator roles: Full Administrator, Sales Operator and Support Operator.
  4. Saves your company name, email, country, time zone and currency as settings, and makes a random cron key.
  5. Tests whether short addresses reach index.php (see "Address style") and saves the result.
  6. Creates the first administrator with the Full Administrator role.
  7. Checks the licence key with the licence server and saves it with the answer.
  8. Writes configuration.php into CoreInto's top folder, next to index.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:

  1. Delete the install folder. While configuration.php exists the installer is closed anyway, but the folder should not stay on a live site.
  2. Add a cron job that runs every 5 minutes. The exact command for your server is shown on the page.
  3. 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):

KeyWhat it does
db_hostDatabase server. Default localhost.
db_portDatabase port. Default 3306.
db_socketA Unix socket path instead of host and port. Empty by default.
db_nameDatabase name. Required.
db_userDatabase user. Required.
db_passDatabase password.
encryption_key32 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_urlThe 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_pathWhere 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_proxiesA 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:

  1. The file named by the COREINTO_CONFIG environment variable, if that variable is set.
  2. coreinto-configuration.php one folder above CoreInto's top folder (outside the web root, which is the safer place).
  3. configuration.php in 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.

FolderHolds
storage/attachments/ticketsTicket attachments
storage/attachments/pdfPDF copies of invoices attached to emails, kept 90 days
storage/filesClient files, under random names
storage/downloadsFiles offered under Support > Downloads
storage/backupsDatabase backups (Settings > Database Backups)
storage/cacheTemporary data, such as registrar domain lists being read
storage/updatesZips of the files replaced by an installed update
storage/logserror-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":

ChoiceAddresses look likeWorks where
index.php?r=/page (works everywhere) ("basic")https://billing.example.com/index.php?r=/client/invoicesEvery web server.
Short addresses: /page ("rewrite")https://billing.example.com/client/invoicesServers 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, .md and .bak files, and files starting with a dot;
  • refuse direct access to app, storage, tests, docs and tools;
  • send /api/v1/ACTION to api/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:

  1. The database. Settings > Database Backups makes a gzip SQL dump into storage/backups on demand and daily (task backup, 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.
  2. configuration.php (or coreinto-configuration.php). It holds the encryption key. Keep a copy with every database backup.
  3. The storage folder: 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

  1. Back up the database first.
  2. Either upload the new files over the old ones (the update zip has no install folder and never contains configuration.php or anything in storage), 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 in storage/updates and writes the new files. That page needs a licence that is in order and PHP's zip extension.
  3. 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.php waits.

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

MenuItems
ClientsView/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
OrdersList All Orders, Pending Orders, Active Orders, Fraud Orders, Cancelled Orders, Add New Order
BillingTransactions 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
SupportSupport 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
ReportsAll Reports, Daily Performance, Income Forecast, Annual Income, New Customers, Ticket Feedback Scores, Batch Invoice PDF Export
UtilitiesAutomation 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-onsLicensing 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.

GroupPages
GeneralGeneral Settings; Automation Settings; Storage Settings (not built yet); Marketing Consent (not built yet)
PaymentsCurrencies; Payment Gateways; Tax Configuration; Promotions
Products and ServicesProducts/Services; Configurable Options; Product Add-ons; Product Bundles; Domain Pricing; Domain Registrars; Servers
SupportSupport Departments; Ticket Statuses; Escalation Rules; Spam Control
SystemAdministrators; 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:

BlockShows
Shortcuts (always)New Client, New Order, New Invoice, New Quote, New Ticket, New To-Do Entry, WHOIS Lookup (those the role allows)
System InformationCoreInto version, PHP and database versions, who is signed in and their role
Staff OnlineAdministrators active in the last 15 minutes

Main area, in the default arrangement:

WidgetShows
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 OverviewA 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".
BillingMoney 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".
SupportTickets awaiting a reply, tickets assigned to you, and the latest five tickets.
Automation OverviewWhen 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 ActivityActive clients, users online in the last hour, and the latest eight client sign-ins with their address.
To-Do ListUp to eight open to-do items that are unassigned or assigned to you. Needs the "To-do list" permission.
Staff OnlineWho is signed in to the admin area and when they were last seen.
Network StatusYour servers with their state, open network issues, and a link to add the first server when there is none.
System HealthGood, 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.
ActivityThe last ten lines of the activity log: date, user, description and IP address. Needs the "Activity log" permission.

Frequently asked questions

What does "Getting started" cover in CoreInto?

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. 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.

Where do I find more help?

Use the Help button on this site, browse the Administrator guide on coreinto.com, or submit a ticket at https://system.coreinto.com/contact with your panel version and the steps you tried.

Submit a ticket