Cherrycake examples version 1.x
Movies search
src/MovieSearch/MovieSearch.php
<?php

namespace CherrycakeApp\MovieSearch;

class MovieSearch extends \Cherrycake\Module {
    protected $dependentCoreModules = [
        "Database",
        "Log",
        "HtmlDocument"
    ];

    public static function mapActions() {
        global $e;

        $e->Actions->mapAction(
            "movieSearchForm",
            new \Cherrycake\Actions\ActionHtml([
                "moduleType" => \Cherrycake\ACTION_MODULE_TYPE_APP,
                "moduleName" => "MovieSearch",
                "methodName" => "form",
                "request" => new \Cherrycake\Actions\Request([
                    "pathComponents" => [
                        new \Cherrycake\Actions\RequestPathComponent([
                            "type" => \Cherrycake\REQUEST_PATH_COMPONENT_TYPE_FIXED,
                            "string" => "movie-search"
                        ]),
                        new \Cherrycake\Actions\RequestPathComponent([
                            "type" => \Cherrycake\REQUEST_PATH_COMPONENT_TYPE_FIXED,
                            "string" => "form"
                        ])
                    ]
                ])
            ])
        );

        $e->Actions->mapAction(
            "movieSearchResult",
            new \Cherrycake\Actions\ActionHtml([
                "moduleType" => \Cherrycake\ACTION_MODULE_TYPE_APP,
                "moduleName" => "MovieSearch",
                "methodName" => "result",
                "request" => new \Cherrycake\Actions\Request([
                    "pathComponents" => [
                        new \Cherrycake\Actions\RequestPathComponent([
                            "type" => \Cherrycake\REQUEST_PATH_COMPONENT_TYPE_FIXED,
                            "string" => "movie-search"
                        ]),
                        new \Cherrycake\Actions\RequestPathComponent([
                            "type" => \Cherrycake\REQUEST_PATH_COMPONENT_TYPE_FIXED,
                            "string" => "result"
                        ])
                    ],
                    "parameters" => [
                        new \Cherrycake\Actions\RequestParameter([
                            "name" => "query",
                            "type" => \Cherrycake\REQUEST_PARAMETER_TYPE_POST
                        ])
                    ]
                ])
            ])
        );
    }

    function form() {
        global $e;

        $e->Output->setResponse(new \Cherrycake\Actions\ResponseTextHtml([
            "code" => \Cherrycake\Output\RESPONSE_OK,
            "payload" =>
                $e->HtmlDocument->header().
                "
                    <form method=post action=\"{$e->Actions->getAction("movieSearchResult")->request->buildUrl()}\">
                        <input name=query type=text placeholder=\"Movie title\" />
                        <input type=submit value=\"Search\"/>
                    </form>
                ".
                $e->HtmlDocument->footer()
        ]));
    }

    function result($request) {
        global $e;

        $e->Log->logEvent(new \CherrycakeApp\LogEventMovieSearch($request->query));

        if (!$request->query) {
            $e->Output->setResponse(new \Cherrycake\Actions\ResponseTextHtml([
                "code" => \Cherrycake\Output\RESPONSE_NOT_FOUND,
                "payload" =>
                    $e->HtmlDocument->header().
                    "No movie title specified".
                    $e->HtmlDocument->footer()
            ]));
            return true;
        }

        $movies = new \CherrycakeApp\Movies([
            "fillMethod" => "fromParameters",
            "p" => [
                "title" => $request->query
            ]
        ]);

        if (!$movies->isAny()) {
            $e->Output->setResponse(new \Cherrycake\Actions\ResponseTextHtml([
                "code" => \Cherrycake\Output\RESPONSE_NOT_FOUND,
                "payload" =>
                    $e->HtmlDocument->header().
                    "No movies found".
                    $e->HtmlDocument->footer()
            ]));
            return true;
        }

        $html = "";
        foreach ($movies as $movie)
            $html .= "{$movie->title} ({$movie->year})<br>";

        $e->Output->setResponse(new \Cherrycake\Actions\ResponseTextHtml([
            "code" => \Cherrycake\Output\RESPONSE_OK,
            "payload" =>
                $e->HtmlDocument->header().
                $html.
                $e->HtmlDocument->footer()
        ]));
    }
}
src/Movies.php
<?php

namespace CherrycakeApp;

class Movies extends \Cherrycake\Items {
    protected $tableName = "movies";
    protected $itemClassName = "\CherrycakeApp\Movie";

    function fillFromParameters($p = false) {
        // Treat parameters
        self::treatParameters($p, [
            "year" => ["default" => false],
            "releasedWhenDirectorWasYoungerThan" => [
                "default" => false
            ],
            "minYear" => ["default" => false],
            "maxYear" => ["default" => false],
            "title" => ["default" => false],
            "orders" => ["addArrayKeysIfNotExist" => [
                "released" => "movies.year asc",
                "title" => "movies.title asc"
            ]]
        ]);

        // Modify $p accordingly
        if ($p["year"]) {
            $p["wheres"][] = [
                "sqlPart" => "movies.year = ?",
                "values" => [
                    [
                        "type" => \Cherrycake\Database\DATABASE_FIELD_TYPE_INTEGER,
                        "value" => $p["year"]
                    ]
                ]
            ];
        }

        if ($p["releasedWhenDirectorWasYoungerThan"]) {
            $p["tables"][] = "directors";
            $p["wheres"][] = ["sqlPart" => "directors.id = movies.directorId"];
            $p["wheres"][] = [
                "sqlPart" => "movies.year - directors.birthYear <= ?",
                "values" => [
                    [
                        "type" => \Cherrycake\Database\DATABASE_FIELD_TYPE_INTEGER,
                        "value" => $p["releasedWhenDirectorWasYoungerThan"]
                    ]
                ]
            ];
        }

        if ($p["minYear"]) {
            $p["wheres"][] = [
                "sqlPart" => "movies.year >= ?",
                "values" => [
                    [
                        "type" => \Cherrycake\Database\DATABASE_FIELD_TYPE_INTEGER,
                        "value" => $p["minYear"]
                    ]
                ]
            ];
        }

        if ($p["maxYear"]) {
            $p["wheres"][] = [
                "sqlPart" => "movies.year <= ?",
                "values" => [
                    [
                        "type" => \Cherrycake\Database\DATABASE_FIELD_TYPE_INTEGER,
                        "value" => $p["maxYear"]
                    ]
                ]
            ];
        }

        if ($p["title"]) {
            $p["wheres"][] = [
                "sqlPart" => "movies.title like ?",
                "values" => [
                    [
                        "type" => \Cherrycake\Database\DATABASE_FIELD_TYPE_STRING,
                        "value" => "%".$p["title"]."%"
                    ]
                ]
            ];
        }

        // Call the parent fillFromParameters
        return parent::fillFromParameters($p);
    }
}
/movie-search/form