Database Plugin
The Database Plugin is for Grav CMS version 1.6+. This plugin facilitates interactions with PHP Data Objects for database access. The intention is this plugin should be used in conjunction with other plugins. For example both Views and Likes-Ratings plugin utilize this plugin to manage SQLite database interactions.
Installation
Installing the Database plugin can be done in one of two ways. The GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file.
It has a requirement of the Grav Database plugin as it stores the views in a simple, file-based sqlite database file. This will automatically be installed if you use GPM.
GPM Installation (Preferred)
The simplest way to install this plugin is via the Grav Package Manager (GPM) through your system's terminal (also called the command line). From the root of your Grav install type:
bin/gpm install database
Requirements
Other than standard Grav requirements, this plugin does have some extra requirements. Database utilizes PHP Data Objects and allows connecting to a number of different database types. This is handled automatically by the plugin, but you do need to ensure you have the following installed on your server:
- Grav 1.6+ or later
- SQLite3 Database (if using SQLite)
- PHP pdo Extension
- PHP pdo_mysql Driver (if using MySQL)
- PHP pdo_pgsql Driver (if using PostgreSQL)
- PHP pdo_sqlite Driver (if using SQLite)
- PHP pdo_sqlsrv Driver (if using Microsoft SQL Server)
| PHP by default should include PDO and the vast majority of linux-based systems have SQLite preinstalled.
Installation of SQLite on Mac systems
SQLite actually comes pre-installed on your Mac, but you can upgrade it to the latest version with Homebrew:
Install Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install SQLite with Homebrew
brew install sqlite
Installation of SQLite on Windows systems
Download the appropriate version of SQLite from the SQLite Downloads Page.
Extract the downloaded ZIP file and run the sqlite3.exe
executable.
Configuration
Configurations are optional, but may be required for some plugins or themes to operate. It is also possible for plugins and themes to operate without configurations, using Ad-Hoc connections.
enabled: true
connections:
mysql:
-
name: connection1
host: localhost
port: 3306
dbname: firstdatabase
charset: utf8mb4
username: firstusername
password: firstpassword
-
name: connection2
host: localhost
port: 3306
dbname: seconddatabase
charset: utf8mb4
username: secondusername
password: secondpassword
sqlite:
-
name: connection1
directory: /path/to
filename: firstdatabase.sqlite
You can configure the Database plugin by using the Admin plugin, navigating to the Plugins list and choosing Database
.
That's the easiest route. Or you can also alter the Plugin configuration by copying the user/plugins/database/database.yaml
file into user/config/plugins/database.yaml
and make your modifications there.
You can add any number of connections, each with a unique name, as array elements beneath the database type.
Currently supported database types are:
MySQL
connections:
mysql:
-
name: connection1
host: localhost
port: 3306
dbname: firstdatabase
charset: utf8mb4
username: firstusername
password: firstpassword
-
name: connection2
host: localhost
port: 3306
dbname: seconddatabase
charset: utf8mb4
username: secondusername
password: secondpassword
pgSQL (PostgreSQL)
connections:
pgsql:
-
name: connection1
host: localhost
port: 5432
dbname: firstdatabase
charset: utf8mb4
username: firstusername
password: firstpassword
-
name: connection2
host: localhost
port: 5432
dbname: seconddatabase
charset: utf8mb4
username: secondusername
password: secondpassword
SQLite
connections:
sqlite:
-
name: connection1
directory: /path/to
filename: firstdatabase.sqlite
-
name: connection2
directory: /path/to
filename: seconddatabase.sqlite
SQLSRV (Microsoft SQL Server)
connections:
sqlsrv:
-
name: connection1
host: localhost
port: 1433
dbname: myfirstdatabase
charset: utf8mb4
username: myfirstusername
password: myfirstpassword
-
name: connection2
host: localhost
port: 1433
dbname: myseconddatabase
charset: utf8mb4
username: mysecondusername
password: mysecondpassword
Usage
Ad-Hoc connections
The plugin will intialize a Database
class in the Grav container, and you can use this to create a new connection or reference an existing connection. I will use some examples from the Views
database to illustrate how it can be used with an ad-hoc connection (not saved in configuration):
/** @var PDO */
protected $db;
protected $config;
protected $path = 'user-data://views';
protected $db_name = 'views.db';
protected $table_total_views = 'total_views';
public function __construct($config)
{
$this->config = new Config($config);
$db_path = Grav::instance()['locator']->findResource($this->path, true, true);
// Create dir if it doesn't exist
if (!file_exists($db_path)) {
Folder::create($db_path);
}
$dsn = 'sqlite:' . $db_path . '/' . $this->db_name;
$this->db = Grav::instance()['database']->connect($dsn);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (!$this->db->tableExists($this->table_total_views)) {
$this->createTables();
}
}
Here you can see a connection string to a sqlite
database in the user/data/views
folder will be used. Then you simply Grav::instance()['database']->connect($dsn)
to initialize and connect to the database. If the tables do not exists, we use a local createTables()
function to create them:
public function createTables()
{
$commands = [
"CREATE TABLE IF NOT EXISTS {$this->table_total_views} (id VARCHAR(255) PRIMARY KEY, count INTEGER DEFAULT 0)",
];
// execute the sql commands to create new tables
foreach ($commands as $command) {
$this->db->exec($command);
}
}
We just exec()
the SQL command to create the tables if they don't exist.
To make simple queries you can follow the example of the get()
method:
public function get($id)
{
$query = "SELECT count FROM {$this->table_total_views} WHERE id = :id";
$statement = $this->db->prepare($query);
$statement->bindValue(':id', $id, PDO::PARAM_STR);
$statement->execute();
$results = $statement->fetch();
return $results['count'] ?? 0;
}
Just a simple SQL query with a prepared statement used to bind query values, in this case the ID of the row we are looking for. The field we are looking for is returned from the function.
Configured connections
You can use configured connections to extend your theme or other plugins. Here is an example of using a configured connection in a theme's twig template:
In your theme's php
/**
* Provide the db variable to twig
*/
public function onTwigSiteVariables(): void
{
$this->grav["twig"]->twig_vars["db"] = Grav::instance()['database'];
}
In your twig template
{% set dbresults = db.mysql("testconnection").selectall("SELECT * FROM testtable WHERE testcol1 != :id", {id: '3'}) %}
{% if dbresults is iterable %}
<table>
<thead>
<tr>
{% for key in dbresults|first|keys %}
<th>{{ key }}</th>
{% endfor %}
<tr>
</thead>
<tbody>
{% for row in dbresults %}
<tr>
{% for col in row %}
<td>{{ col }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
In this case, we are using a configured connection with the name testconnection
, querying a table named testtable
, looking for results where the value of testcol1
is not equal to 3
. The example shows how to bind a named parameter with the value 3
to the name :id
. The results are displayed as a table, with the column headers as headers in table
Methods
The main methods that the Database
class understands are: select
, selectall
, update
, delete
, insert
. However, you can use any PDO command.