Get up to 80 % extra points for free! More info:

Discussion – Lesson 6 - NOO-CMS - Article editor in PHP

Back

 

Comments
Avatar
lawrence njoroge:3/10/2017 13:35

help me out i cant fix the error
"
Fatal error: Call to a member function prepare() on null in C:\xampp\htdoc­s\PhpProject1\dbb­.php on line 66"

dbb.php

<?php

/*
 *       _____ _____ _____                _       _
 *      |_   _/  __ \_   _|              (_)     | |
 *        | | | /  \/ | |  ___  ___   ___ _  __ _| |
 *        | | ||      | | / __|/ _ \ / __| |/ _` | |
 *       _| |_| \__/\ | |_\__ \ (_) | (__| | (_| | |
 *      |_____\_____/ |_(_)___/\___/ \___|_|\__,_|_|
 *                   ___
 *                  |  _|___ ___ ___
 *                  |  _|  _| -_| -_|  LICENCE
 *                  |_| |_| |___|___|
 *
 * IT NEWS  <>  PROGRAMMING  <>  HW & SW  <>  COMMUNITY
 *
 * This source code is part of online courses at IT social
 * network WWW.ICT.SOCIAL
 *
 * Feel free to use it for whatever you want, modify it and share it but
 * don't forget to keep this link in code.
 *
 * For more information visit http://www.ict.social/licences
 *
 * A simple database wrapper over the PDO class
 */
class Db
{
        /**
         * @var PDO A database connection
         */
        private static $connection;

        /**
         * @var array The default driver settings
         */
        private static $options = array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
                PDO::ATTR_EMULATE_PREPARES => false,
        );

        /**
         * Connects to the database using given credentials
         * @param string $host Host name
         * @param string $database Database name
         * @param string $user Username
         * @param string $password Password
         */
        public static function connect($host, $database, $user)
        {
                if (!isset(self::$connection)) {
                        $dsn = "mysql:host=$host;dbname=$database";
                        self::$connection = new PDO($dsn, $user,  self::$options);
                }
        }

        /**
         * Executes a query and returns the PDO statement
         * @param array $params An array where the first item represents the query and the other items are its parameters.
         * @return \PDOStatement PDO statement
         */
        private static function executeStatement($params)
        {
                $query = array_shift($params);
                $statement = self::$connection->prepare($query);
                $statement->execute($params);
                return $statement;
        }

        /**
         * Executes a query and returns the number of affected rows.
         * Any other parameters will be passed into the query.
         * @param string $query The query
         * @return int The number of affected rows
         */
        public static function query($query) {
                $statement = self::executeStatement(func_get_args());
                return $statement->rowCount();
        }

        /**
         * Executes a query and returns the value of the first column of the first row.
         * Any other parameters will be passed into the query.
         * @param string $query The query
         * @return mixed The value of the first column of the first row
         */
        public static function querySingle($query) {
                $statement = self::executeStatement(func_get_args());
                $data = $statement->fetch();
                return $data[0];
        }

        /**
         * Executes a query and returns the first row of the result.
         * Any other parameters will be passed into the query.
         * @param string $query The query
         * @return mixed An associative array representing the row or false in no data returned
         */
        public static function queryOne($query) {
                $statement = self::executeStatement(func_get_args());
                return $statement->fetch(PDO::FETCH_ASSOC);
        }

        /**
         * Executes a query and returns all resulting rows as an array of associative arrays.
         * Any other parameters will be passed into the query.
         * @param string $query The query
         * @return mixed An array of associative arrays or false in no data returned
         */
        public static function queryAll($query) {
                $statement = self::executeStatement(func_get_args());
                return $statement->fetchAll(PDO::FETCH_ASSOC);
        }

        /**
         * Inserts data from an associative array into the database as a new row
         * @param string $table The table name
         * @param array $data The associative array where keys preresent columns and values their values
         * @return int The number of affected rows
         */
        public static function insert($table, $data) {
                $keys = array_keys($data);
                self::checkIdentifiers(array($table) + $keys);
                $query = "
                        INSERT INTO `$table` (`" . implode('`, `', $keys) . "`)
                        VALUES (" . str_repeat('?,', count($data) - 1) . "?)
                ";
                $params = array_merge(array($query), array_values($data));
                $statement = self::executeStatement($params);
                return $statement->rowCount();
        }

        /**
         * Executes an update and passes data from an associative array to it
         * @param string $table The table name
         * @param array $data The associative array where keys preresent columns and values their values
         * @param string $condition A string containing the condition (WHERE)
         * @return mixed The number of affected rows
         */
        public static function update($table, $data, $condition) {
                $keys = array_keys($data);
                self::checkIdentifiers(array($table) + $keys);
                $query = "
                        UPDATE `$table` SET `".
                        implode('` = ?, `', array_keys($data)) . "` = ?
                        $condition
                ";
                $params = array_merge(array($query), array_values($data), array_slice(func_get_args(), 3));
                $statement = self::executeStatement($params);
                return $statement->rowCount();
        }

        /**
         * Returns the ID of the last inserted row
         * @return mixed The ID of the last inserted row
         */
        public static function getLastId()
        {
                return self::$connection->lastInsertId();
        }

        /**
         * Quotes a given string to protect it against the SQL injection
         * @param string $string The string
         * @return mixed The quoted string
         */
        public static function quote($string)
        {
                return self::$connection->quote($string);
        }

        /**
         * Checks whether given identifiers don't contain dangerous characters
         * @param array $identifiers The identifiers
         * @throws \Exception
         */
        private static function checkIdentifiers($identifiers)
        {
                foreach ($identifiers as $identifier)
                {
                        if (!preg_match('/^[a-zA-Z0-9\_\-]+$/u', $identifier))
                                throw new Exception('Dangerous identifier in SQL query');
                }
        }
}

editor.php code

<?php
session_start();

require('Dbb.php');

$article = array(
        'article_id' => '',
        'title' => '',
        'content' => '',
        'description' => '',
);
if ($_POST)
{
        if (!$_POST['article_id'])
        {
                Db::query('
                        INSERT INTO article (title, content, description)
                        VALUES (?, ?, ?, ?)
                ', $_POST['title'], $_POST['content'], $_POST['description']);
        }
        else
        {
                Db::query('
                        UPDATE article
                        SET title=?, content=?,  description=?
                        WHERE article_id=?
                ', $_POST['title'], $_POST['content'], $_POST['description'], $_POST['article_id']);
        }
        header('Location: index.php');
        exit();
}
else
?>
<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" type="text/css" />
        <title>Article editor</title>
</head>

<body>
    <header>
                        <div id="logo"><h1></h1></div>
                <nav>
                        <ul>
                            <li><a href="home.php">Home</a></li>
                                <li><a href="about.php">About us</a></li>
                                <li><a href="members.php">members</a></li>
                                <li><a href="contact.php">Contact</a></li>


                        </ul>
                </nav>
</header>
        <article>
                <div id="centerer">
                        <header>
                                <h1>Article editor</h1>
                        </header>
                        <section>

                                <form method="post">
                                        <input type="hidden" name="article_id" value="<?= htmlspecialchars($article['article_id']) ?>" /><br />
                                        title<br />
                                        <input type="text" name="title" value="<?= htmlspecialchars($article['title']) ?>" /><br />
                                        Description<br />
                                        <input type="text" name="description" value="<?= htmlspecialchars($article['description']) ?>" /><br />
                                        <textarea name="content"><?= htmlspecialchars($article['content']) ?></textarea>
                                        <input type="submit" value="Submit" />
                                </form>
                        </section>
                        <div class="clear"></div>
                </div>
        </article>
        <script type="text/javascript" src="//cdn.tinymce.com/4/tinymce.min.js"></script>
        <script type="text/javascript">
                tinymce.init({
                        selector: "textarea[name=content]",
                        plugins: [
                                "advlist autolink lists link image charmap print preview anchor",
                                "searchreplace visualblocks code fullscreen",
                                "insertdatetime media table contextmenu paste"
                        ],
                        toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
                        entities: "160,nbsp",
                        entity_encoding: "named",
                        entity_encoding: "raw"
                });
        </script>
     <footer>
                        Made by &copy;<a href="http://www.facebook.com/lawnj">lawrence</a>
                </footer>
</body>
</html>
Reply
3/10/2017 13:35
where there is will there is a way
Avatar
IT Man
Member
Avatar
Replies to lawrence njoroge
IT Man:3/10/2017 16:31

You have 4 question marks in INSERT and only 3 variables. So remove 1 question mark. :)
Btw. you can use insert() instead query(). Check the function. :)

 
Reply
3/10/2017 16:31
Avatar
lawrence njoroge:3/11/2017 12:13

more help please
"Warning: array_keys() expects parameter 1 to be array, string given in C:\xampp\htdoc­s\PhpProject1\dbb­.php on line 123

Fatal error: Unsupported operand types in C:\xampp\htdoc­s\PhpProject1\dbb­.php on line 124"
dbb.php

<?php

/*
 *       _____ _____ _____                _       _
 *      |_   _/  __ \_   _|              (_)     | |
 *        | | | /  \/ | |  ___  ___   ___ _  __ _| |
 *        | | ||      | | / __|/ _ \ / __| |/ _` | |
 *       _| |_| \__/\ | |_\__ \ (_) | (__| | (_| | |
 *      |_____\_____/ |_(_)___/\___/ \___|_|\__,_|_|
 *                   ___
 *                  |  _|___ ___ ___
 *                  |  _|  _| -_| -_|  LICENCE
 *                  |_| |_| |___|___|
 *
 * IT NEWS  <>  PROGRAMMING  <>  HW & SW  <>  COMMUNITY
 *
 * This source code is part of online courses at IT social
 * network WWW.ICT.SOCIAL
 *
 * Feel free to use it for whatever you want, modify it and share it but
 * don't forget to keep this link in code.
 *
 * For more information visit http://www.ict.social/licences
 *
 * A simple database wrapper over the PDO class
 */
class Db
{
        /**
         * @var PDO A database connection
         */
        private static $connection;

        /**
         * @var array The default driver settings
         */
        private static $options = array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
                PDO::ATTR_EMULATE_PREPARES => false,
        );

        /**
         * Connects to the database using given credentials
         * @param string $host Host name
         * @param string $database Database name
         * @param string $user Username
         * @param string $password Password
         */
        public static function connect($host, $database, $user)
        {
                if (!isset(self::$connection)) {
                        $dsn = "mysql:host=$host;dbname=$database";
                        self::$connection = new PDO($dsn, $user,  self::$options);
                }
        }

        /**
         * Executes a query and returns the PDO statement
         * @param array $params An array where the first item represents the query and the other items are its parameters.
         * @return \PDOStatement PDO statement
         */
        private static function executeStatement($params)
        {
                $insert = array_shift($params);
                $statement = self::$connection->prepare($insert);
                $statement->execute($params);
                return $statement;
        }

        /**
         * Executes a query and returns the number of affected rows.
         * Any other parameters will be passed into the query.
         * @param string $insert The query
         * @return int The number of affected rows
         */
        public static function query($insert) {
                $statement = self::executeStatement(func_get_args());
                return $statement->rowCount();
        }

        /**
         * Executes a query and returns the value of the first column of the first row.
         * Any other parameters will be passed into the query.
         * @param string $insert The query
         * @return mixed The value of the first column of the first row
         */
        public static function querySingle($insert) {
                $statement = self::executeStatement(func_get_args());
                $data = $statement->fetch();
                return $data[0];
        }

        /**
         * Executes a query and returns the first row of the result.
         * Any other parameters will be passed into the query.
         * @param string $insert The query
         * @return mixed An associative array representing the row or false in no data returned
         */
        public static function queryOne($insert) {
                $statement = self::executeStatement(func_get_args());
                return $statement->fetch(PDO::FETCH_ASSOC);
        }

        /**
         * Executes a query and returns all resulting rows as an array of associative arrays.
         * Any other parameters will be passed into the query.
         * @param string $insert The query
         * @return mixed An array of associative arrays or false in no data returned
         */
        public static function queryAll($insert) {
                $statement = self::executeStatement(func_get_args());
                return $statement->fetchAll(PDO::FETCH_ASSOC);
        }

        /**
         * Inserts data from an associative array into the database as a new row
         * @param string $table The table name
         * @param array $data The associative array where keys preresent columns and values their values
         * @return int The number of affected rows
         */
        public static function insert($table, $data) {
                $keys = array_keys($table);
                self::checkIdentifiers(array($table) + $keys);
                $insert = "
                        INSERT INTO `$table` (`" . implode('`, `', $keys) . "`)
                        VALUES (" . str_repeat('?,', count($data) - 1) . "?)
                ";
                $params = array_merge(array($insert), array_values($data));
                $statement = self::executeStatement($params);
                return $statement->rowCount();
        }

        /**
         * Executes an update and passes data from an associative array to it
         * @param string $table The table name
         * @param array $data The associative array where keys preresent columns and values their values
         * @param string $condition A string containing the condition (WHERE)
         * @return mixed The number of affected rows
         */
        public static function update($table, $data, $condition) {
                $keys = array_keys($data);
                self::checkIdentifiers(array($table) + $keys);
                $insert = "
                        UPDATE `$table` SET `".
                        implode('` = ?, `', array_keys($data)) . "` = ?
                        $condition
                ";
                $params = array_merge(array($insert), array_values($data), array_slice(func_get_args(), 3));
                $statement = self::executeStatement($params);
                return $statement->rowCount();
        }

        /**
         * Returns the ID of the last inserted row
         * @return mixed The ID of the last inserted row
         */
        public static function getLastId()
        {
                return self::$connection->lastInsertId();
        }

        /**
         * Quotes a given string to protect it against the SQL injection
         * @param string $string The string
         * @return mixed The quoted string
         */
        public static function quote($string)
        {
                return self::$connection->quote($string);
        }

        /**
         * Checks whether given identifiers don't contain dangerous characters
         * @param array $identifiers The identifiers
         * @throws \Exception
         */
        private static function checkIdentifiers($identifiers)
        {
                foreach ($identifiers as $identifier)
                {
                    if (!preg_match('/^[a-zA-Z0-9\_\-]+$/u', $identifier)) {
                throw new Exception('Dangerous identifier in SQL query');
            }
        }
        }
}

editor.php
<?php
session_start();

require('Dbb.php');

$article = array(
        'article_id' => '',
        'title' => '',
        'content' => '',
        'description' => '',
);
if ($_POST)
{
        if (!$_POST['article_id'])
        {
                Db::insert('
                        INSERT INTO article (title, content, description)
                        VALUES (?, ?, ?)
                ', $_POST['title'], $_POST['content'], $_POST['description']);
        }
        else
        {
                Db::insert('
                        UPDATE article
                        SET title=?, content=?,  description=?
                        WHERE article_id=?
                ', $_POST['title'], $_POST['content'], $_POST['description'], $_POST['article_id']);
        }
        header('Location: index.php');
        exit();
}
else
?>
<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" type="text/css" />
        <title>Article editor</title>
</head>

<body>
    <header>
                        <div id="logo"><h1></h1></div>
                <nav>
                        <ul>
                            <li><a href="home.php">Home</a></li>
                                <li><a href="about.php">About us</a></li>
                                <li><a href="members.php">members</a></li>
                                <li><a href="contact.php">Contact</a></li>


                        </ul>
                </nav>
</header>
        <article>
                <div id="centerer">
                        <header>
                                <h1>Article editor</h1>
                        </header>
                        <section>

                                <form method="post">
                                        <input type="hidden" name="article_id" value="<?= htmlspecialchars($article['article_id']) ?>" /><br />
                                        title<br />
                                        <input type="text" name="title" value="<?= htmlspecialchars($article['title']) ?>" /><br />
                                        Description<br />
                                        <input type="text" name="description" value="<?= htmlspecialchars($article['description']) ?>" /><br />
                                        <textarea name="content"><?= htmlspecialchars($article['content']) ?></textarea>
                                        <input type="submit" value="Submit" />
                                </form>
                        </section>
                        <div class="clear"></div>
                </div>
        </article>
        <script type="text/javascript" src="//cdn.tinymce.com/4/tinymce.min.js"></script>
        <script type="text/javascript">
                tinymce.init({
                        selector: "textarea[name=content]",
                        plugins: [
                                "advlist autolink lists link image charmap print preview anchor",
                                "searchreplace visualblocks code fullscreen",
                                "insertdatetime media table contextmenu paste"
                        ],
                        toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
                        entities: "160,nbsp",
                        entity_encoding: "named",
                        entity_encoding: "raw"
                });
        </script>
     <footer>
                        Made by &copy;<a href="http://www.facebook.com/lawnj">lawrence</a>
                </footer>
</body>
</html>

\---

Reply
3/11/2017 12:13
where there is will there is a way
Avatar
IT Man
Member
Avatar
Replies to lawrence njoroge
IT Man:3/11/2017 16:10

insert has only 2 parameters - first is table (String) and then data (array). So you have to change it in this:

Db::insert('article', array(
    'title' => $_POST['title'],
    'content' => $_POST['content'],
    'description' => $_POST['description']
));

For update use normally function query. So for edit article you will use this:

Db::query('
        UPDATE article
        SET title=?, content=?, url=?, description=?
        WHERE article_id=?
', $_POST['title'], $_POST['content'], $_POST['url'], $_POST['description'], $_POST['article_id']);

I hope I helped you and next time you can use forum. :)

 
Reply
3/11/2017 16:10
Avatar
Kev Harris
Member
Avatar
Kev Harris:1/16/2020 15:41

In the PHP code for the editor.php file above, both the INSERT and UPDATE queries have

$_POST['keywords']

in it, however the database was not set up to accept this field, am I to assume this is an error in your code or am I going to see this come into effect later in another chapter?

Reply
1/16/2020 15:41
Dream like you will live forever, Live like you will die tomorrow.
Avatar
Kev Harris
Member
Avatar
Kev Harris:1/16/2020 15:48

I thought it best to mention, that I have removed these two from my code to allow the article to be added to the database.

Reply
1/16/2020 15:48
Dream like you will live forever, Live like you will die tomorrow.
Avatar
Sid Smarty
Member
Avatar
Sid Smarty:6/30/2020 7:28

There is a missing database file in zip folder

 
Reply
6/30/2020 7:28
Avatar
Replies to Sid Smarty
David Capka Hartinger:7/1/2020 5:01

Hi Sid, all the DB commands are in the articles, you can create the DB easily.

Reply
7/1/2020 5:01
You can walk through a storm and feel the wind but you know you are not the wind.
To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

8 messages from 18 displayed.