<commit_before><?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="learning.quickstart.create-model">
    <title>Create a Model and Database Table</title>

    <para>
        Before we get started, let's consider something: where will these classes live, and how will
        we find them? The default project we created instantiates an autoloader. We can attach other
        autoloaders to it so that it knows where to find different classes. Typically, we want our
        various MVC classes grouped under the same tree -- in this case,
        <filename>application/</filename> -- and most often using a common prefix.
    </para>

    <para>
        <classname>Zend_Controller_Front</classname> has a notion of "modules", which are individual
        mini-applications.  Modules mimic the directory structure that the <command>zf</command>
        tool sets up under <filename>application/</filename>, and all classes inside them are
        assumed to begin with a common prefix, the module name.  <filename>application/</filename>
        is itself a module -- the "default" or "application" module. As such, we'll want to setup autoloading for resources
        within this directory.
    </para>

    <para>
        <classname>Zend_Application_Module_Autoloader</classname> provides the functionality needed
        to map the various resources under a module to the appropriate directories, and provides a
        standard naming mechanism as well. An instance of the class is created by default during
        initialization of the bootstrap object; your application bootstrap will be default use the
        module prefix "Application". As such, our models, forms, and table classes will all begin
        with the class prefix "Application_".
    </para>

   <para>
        Now, let's consider what makes up a guestbook. Typically, they are simply a list of entries
        with a <emphasis>comment</emphasis>, <emphasis>timestamp</emphasis>, and, often,
        <emphasis>email address</emphasis>. Assuming we store them in a database, we may also want a
        <emphasis>unique identifier</emphasis> for each entry. We'll likely want to be able to save
        an entry, fetch individual entries, and retrieve all entries. As such, a simple guestbook
        model API might look something like this:
    </para>

    <programlisting language="php"><![CDATA[
// application/models/Guestbook.php

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __set($name, $value);
    public function __get($name);

    public function setComment($text);
    public function getComment();

    public function setEmail($email);
    public function getEmail();

    public function setCreated($ts);
    public function getCreated();

    public function setId($id);
    public function getId();
}

class Application_Model_GuestbookMapper
{
    public function save(Application_Model_Guestbook $guestbook);
    public function find($id);
    public function fetchAll();
}
]]></programlisting>

    <para>
        <methodname>__get()</methodname> and <methodname>__set()</methodname> will provide a
        convenience mechanism for us to access the individual entry properties, and proxy to the
        other getters and setters. They also will help ensure that only properties we whitelist will
        be available in the object.
    </para>

    <para>
        <methodname>find()</methodname> and <methodname>fetchAll()</methodname> provide the ability
        to fetch a single entry or all entries, while <methodname>save()</methodname> takes care of
        saving an entry to the data store.
    </para>

    <para>
        Now from here, we can start thinking about setting up our database.
    </para>

    <para>
        First we need to initialize our <classname>Db</classname> resource. As with the
        <classname>Layout</classname> and <classname>View</classname> resource, we can provide
        configuration for the <classname>Db</classname> resource. We can do this with the
        <command>zf configure db-adapter</command> command:
    </para>

    <programlisting language="shell"><![CDATA[
% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH % "/../data/db/guestbook.db"' \
> -s production
A db configuration for the production has been written to the application config file.

% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH % "/../data/db/guestbook-testing.db"' \
> -s testing
A db configuration for the production has been written to the application config file.

% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH % "/../data/db/guestbook-dev.db"' \
> -s development
A db configuration for the production has been written to the application config file.
]]></programlisting>

    <para>
        Now edit your <filename>application/configs/application.ini</filename> file, where you'll
        see the following lines were added in the appropriate sections.
    </para>

    <programlisting language="ini"><![CDATA[
; application/configs/application.ini

[production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = "APPLICATION_PATH "/../data/db/guestbook.db""

[testing : production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = "APPLICATION_PATH "/../data/db/guestbook-testing.db""

[development : production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = "APPLICATION_PATH "/../data/db/guestbook-dev.db""
]]></programlisting>

    <para>
        If you look carefully, you'll notice a slight problem: the
        <constant>APPLICATION_PATH</constant> constant is within quotes; this is due to limitations
        of the INI format. Edit the file so that the lines look as follows (ensure you also remove
        the extra quote at the end of the lines):
    </para>

    <programlisting language="ini"><![CDATA[
; application/configs/application.ini

[production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"

[testing : production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"

[development : production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
]]></programlisting>

    <para>
        Your final configuration file should look like the following:
    </para>
<commit_msg>[DOCS] Removed obsolete verbiage from db-adapter configuration section<commit_after><?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="learning.quickstart.create-model">
    <title>Create a Model and Database Table</title>

    <para>
        Before we get started, let's consider something: where will these classes live, and how will
        we find them? The default project we created instantiates an autoloader. We can attach other
        autoloaders to it so that it knows where to find different classes. Typically, we want our
        various MVC classes grouped under the same tree -- in this case,
        <filename>application/</filename> -- and most often using a common prefix.
    </para>

    <para>
        <classname>Zend_Controller_Front</classname> has a notion of "modules", which are individual
        mini-applications.  Modules mimic the directory structure that the <command>zf</command>
        tool sets up under <filename>application/</filename>, and all classes inside them are
        assumed to begin with a common prefix, the module name.  <filename>application/</filename>
        is itself a module -- the "default" or "application" module. As such, we'll want to setup autoloading for resources
        within this directory.
    </para>

    <para>
        <classname>Zend_Application_Module_Autoloader</classname> provides the functionality needed
        to map the various resources under a module to the appropriate directories, and provides a
        standard naming mechanism as well. An instance of the class is created by default during
        initialization of the bootstrap object; your application bootstrap will be default use the
        module prefix "Application". As such, our models, forms, and table classes will all begin
        with the class prefix "Application_".
    </para>

   <para>
        Now, let's consider what makes up a guestbook. Typically, they are simply a list of entries
        with a <emphasis>comment</emphasis>, <emphasis>timestamp</emphasis>, and, often,
        <emphasis>email address</emphasis>. Assuming we store them in a database, we may also want a
        <emphasis>unique identifier</emphasis> for each entry. We'll likely want to be able to save
        an entry, fetch individual entries, and retrieve all entries. As such, a simple guestbook
        model API might look something like this:
    </para>

    <programlisting language="php"><![CDATA[
// application/models/Guestbook.php

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __set($name, $value);
    public function __get($name);

    public function setComment($text);
    public function getComment();

    public function setEmail($email);
    public function getEmail();

    public function setCreated($ts);
    public function getCreated();

    public function setId($id);
    public function getId();
}

class Application_Model_GuestbookMapper
{
    public function save(Application_Model_Guestbook $guestbook);
    public function find($id);
    public function fetchAll();
}
]]></programlisting>

    <para>
        <methodname>__get()</methodname> and <methodname>__set()</methodname> will provide a
        convenience mechanism for us to access the individual entry properties, and proxy to the
        other getters and setters. They also will help ensure that only properties we whitelist will
        be available in the object.
    </para>

    <para>
        <methodname>find()</methodname> and <methodname>fetchAll()</methodname> provide the ability
        to fetch a single entry or all entries, while <methodname>save()</methodname> takes care of
        saving an entry to the data store.
    </para>

    <para>
        Now from here, we can start thinking about setting up our database.
    </para>

    <para>
        First we need to initialize our <classname>Db</classname> resource. As with the
        <classname>Layout</classname> and <classname>View</classname> resource, we can provide
        configuration for the <classname>Db</classname> resource. We can do this with the
        <command>zf configure db-adapter</command> command:
    </para>

    <programlisting language="shell"><![CDATA[
% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' \
> production
A db configuration for the production has been written to the application config file.

% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-testing.db"' \
> testing
A db configuration for the production has been written to the application config file.

% zf configure db-adapter \
> 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook-dev.db"' \
> development
A db configuration for the production has been written to the application config file.
]]></programlisting>

    <para>
        Now edit your <filename>application/configs/application.ini</filename> file, where you'll
        see the following lines were added in the appropriate sections.
    </para>

    <programlisting language="ini"><![CDATA[
; application/configs/application.ini

[production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook.db"

[testing : production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-testing.db"

[development : production]
; ...
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/guestbook-dev.db"
]]></programlisting>

    <para>
        Your final configuration file should look like the following:
    </para>

{'fraction_non_alphanumeric': 0.09767141009055627, 'fraction_numerical': 0.000646830530401035, 'mean_word_length': 3.466955579631636, 'pattern_counts': {'":': 0, '<': 162, '<?xml version=': 2, '>': 174, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3833267', 'n_tokens_mistral': 3402, 'n_tokens_neox': 3256, 'n_words': 1237}