<?php
/**
 * -------------------------------------------------------------------------
 *
 * Module for working with the "newspapers" database table.
 *
 * -------------------------------------------------------------------------
 *
 * @license  GPL-2.0  https://opensource.org/license/gpl-2-0/
 * @author   MiMiMi Community
 *
 * -------------------------------------------------------------------------
 */

mimimiInclude( 'NodeWithTable.php' );
class MyMimimiNewspapers extends MimimiNodeModuleWithTable {

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 2: You need to specify a name of the database table to store
     *         newspapers. It is quite logical to assume that the name of
     *         this table will correspond to its purpose, for example,
     *         "newspapers". Please note that due to MySQL naming
     *         restrictions, the maximum length of a table name is 64
     *         characters. Do not exceed that length, otherwise you will
     *         receive an error message.
     *
     * ---------------------------------------------------------------------
     *
     * @access protected
     * @var    string
     *
     * ---------------------------------------------------------------------
     */

    protected $table = 'newspapers';

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 3: You need to define a database table structure. Please note
     *         that the newspaper database is divided into primary and
     *         secondary tables. This is done in order to avoid processing
     *         unnecessary information when obtaining a simple list of
     *         newspapers for the home page or sitemap. The primary table
     *         is presented below. It stores general information about
     *         posted newspapers. The secondary table "newspapers_articles"
     *         is presented in the "newspaper/Newspapers/Articles/Articles.php"
     *         submodule. It stores information about articles in newspapers
     *         issues and is only used on the newspaper's view page. Also
     *         note that due to MySQL naming restrictions, the maximum
     *         length of a table column name is 64 characters.
     *
     * ---------------------------------------------------------------------
     *
     * @access protected
     * @var    array
     *
     * ---------------------------------------------------------------------
     */

    protected $tableFields = [
                  '`id`         BIGINT(20)    NOT NULL  AUTO_INCREMENT             COMMENT "unique newspaper identifier"',
                  '`enabled`    BOOLEAN       NOT NULL  DEFAULT FALSE              COMMENT "1 if allow display it for all"',
                  '`language`   VARCHAR(25)   NOT NULL  DEFAULT "en-US"            COMMENT "language attribute for page HTML tag"',
                  '`url`        VARCHAR(255)  NOT NULL                             COMMENT "unique address of this newspaper"',
                  '`credits`    VARCHAR(255)  NOT NULL                             COMMENT "credits link if it is reposting"',
                  '`edition`    VARCHAR(25)   NOT NULL                             COMMENT "newspaper name in header"',
                  '`slogan`     VARCHAR(50)   NOT NULL                             COMMENT "newspaper slogan in header"',
                  '`number`     VARCHAR(25)   NOT NULL                             COMMENT "newspaper numerator in header"',
                  '`sidebar`    VARCHAR(50)   NOT NULL                             COMMENT "sidebar title"',
                  '`date`       TIMESTAMP     NOT NULL  DEFAULT CURRENT_TIMESTAMP  COMMENT "newspaper date in header"',
                  '`meta`       VARCHAR(510)  NOT NULL                             COMMENT "summary text for page meta description tag"',
                  '`copyright`  VARCHAR(150)  NOT NULL                             COMMENT "newspaper copyright in footer"'
              ];

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 4: You need to define a list of table keys to speed up the
     *         database operations related to newspapers. According to the
     *         requirements of your web application, there are four main
     *         operations: update by ID, search by URL, sort by date, filter
     *         by moderation flag. So you only need to define the four keys
     *         below.
     *
     * ---------------------------------------------------------------------
     *
     * @access protected
     * @var    array
     *
     * ---------------------------------------------------------------------
     */

    protected $tableKeys = [
                  'PRIMARY KEY ( `id`      )',
                  'UNIQUE  KEY ( `url`     )',
                  'KEY         ( `date`    )',
                  'KEY         ( `enabled` )'
              ];

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 5: You should specify demo rows that will be used as default
     *         newspaper entries if the database does not have a table named
     *         "newspapers". In this case, all demo rows will be automatically
     *         added to the newly created primary and secondary tables. Please
     *         note that the secondary table entries are located under the
     *         "articles" index.
     *
     * ---------------------------------------------------------------------
     *
     * @access protected
     * @var    array
     *
     * ---------------------------------------------------------------------
     */

    protected $demoRows = [
        [
            'id'        => 1,
            'enabled'   => FALSE,
            'language'  => 'en-US',
            'url'       => 'demo-newspaper-issue-1',
            'credits'   => 'https://codepen.io/oliviale/pen/BaoXOOP',
            'edition'   => 'The Original demo',
            'slogan'    => 'Two Memes Edition',
            'number'    => 'Issue #1',
            'sidebar'   => 'Hot this month',
            'date'      => '2020-05-26 11:22:33',
            'meta'      => 'This is a great example of a responsive CSS Grid layout with a newspaper theme! It is designed by Olivia Ng, a UI/UX developer with 7 years of experience in web design and development.',
            'copyright' => '© 2020 A Pen by Olivia Ng on Codepen',
            'articles'  => [
                [
                    'owner'     => 1,
                    'order'     => 0,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-CCI',
                    'decor'     => 'no-decor',
                    'h1'        => 'Woman spends too much time on Codepens despite advice; no plans to stop',
                    'text'      => 'Sometimes, Internet users land themselves in an uncommon situation where an app or website can be used for both work and personal situations. Well, a young front-end designer was spending up to 13 hours on the site, Codepen for work and her hobby, which unfortunately, is also coding.' . "\r\n" .
                                   'The designer, whose work includes a To-Do Terrarium, clarified, "Well, I didn\'t have to use it for work but it was already part of my workflow. It just made sense as it was more efficient". The biggest issue, she said, is that she would hop on Codepen for work, but would get distracted by pens made by others in the community for unexpectedly long periods of time, which then causes her to spend even more time on the site.' . "\r\n" .
                                   '"I mean, that\'s terrible right?" she asked. Codepen, which brands itself as the best place to build, test, and discover front-end code, has declined to comment at this time.',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-terrarium.jpg',
                    'image_alt' => 'A to-do list that grows succulents when you\'ve completed a task',
                    'credits'   => 'https://codepen.io/oliviale/full/oNXJgEM'
                ], [
                    'owner'     => 1,
                    'order'     => 1,
                    'size'      => 'size2x2',
                    'layout'    => 'layoutI-T-CC',
                    'decor'     => 'borderB',
                    'h1'        => 'Can you get inspired to make your own floor plans?',
                    'text'      => 'Making a floor Plan with CSS Grid? Talk about using the wrong tool for the job. But I guess this is what happens when someone isn\'t happy with any of the floor plans found on Pinterest; she\'ll start making her own for the eventual home that she will never own. Nevertheless, there\'s a home office with a large window to look out of pensively during rainy days and a ton of "white space" for the cats to run around.',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-floorplan.jpg',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/moLrBq'
                ], [
                    'owner'     => 1,
                    'order'     => 2,
                    'size'      => 'size1x2',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'contour',
                    'h1'        => '50% Off Hogwarts Express tickets',
                    'text'      => 'Limited time offer',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-hogwarts.svg',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/MZZYyO'
                ], [
                    'owner'     => 1,
                    'order'     => 3,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'borderT',
                    'h1'        => 'A pasta menu',
                    'text'      => 'Everybody loves pasta. It\'s impossible to not love them, so here are 15 recipes, served with GSAP. Note the easter egg - the menu icon changes according to the pasta that you choose.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/zYvxXWw'
                ], [
                    'owner'     => 1,
                    'order'     => 4,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'borderTB',
                    'h1'        => 'Marvel at a magazine',
                    'text'      => 'A tribute of sorts to an era of cool superhero movies, this is a Marvel-themed magazine! Recommended, because it took 45 hours, so you know some serious dedication has been poured into this.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/GRKQoKM'
                ], [
                    'owner'     => 1,
                    'order'     => 5,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Let\'s adopt, don\'t shop.',
                    'text'      => 'Explore a style guide and various page layouts for a pet adoption site in the Style Guide collection. Inspired by the Atomic Design principle, this 8-pen collection includes a 404 page concept, an admin dashboard and what a Twitter user calls a "media card zen garden". Each pen comes with five (yes, five) color themes, including the precious dark mode.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/collection/XJyNPm'
                ], [
                    'owner'     => 1,
                    'order'     => 6,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutI-T-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Toggles',
                    'text'      => 'Eight playful toggles to toggle on and off for your amusement. Is it possible to use these on your site and still adhere to assessibility rules? No. But there\'s a really cute dog one you have to see.',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-toggle.gif',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/xxboXzo'
                ], [
                    'owner'     => 1,
                    'order'     => 7,
                    'size'      => 'size2x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-menu.jpg',
                    'image_alt' => 'See the new and improved menu for Toasty!',
                    'credits'   => 'https://codepen.io/oliviale/full/LYYrKMV'
                ], [
                    'owner'     => 1,
                    'order'     => 8,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutIT-C',
                    'decor'     => 'filled',
                    'h1'        => 'World News',
                    'text'      => 'Looks like Covid-19 is gonna be around for a while so here is another friendly reminder to practice social distancing. Oh, and wear a mask!',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-social.gif',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/QWjjrZX'
                ], [
                    'owner'     => 1,
                    'order'     => 9,
                    'size'      => 'size5x1',
                    'layout'    => 'layoutIT-CCC',
                    'decor'     => 'borderT',
                    'h1'        => 'More CSS Grid things like this one. Shelves, coupons and more!',
                    'text'      => 'Get your fill of more CSS Grid items in this collection. There are a total of 32 pens to date... well, 33, if you count this one too. What can you expect in this collection? The hidden gems, in my totally unbiased opinion, are the recreation of the Pac-Man layout and coupons inspired by junk mail. A lot of joke items of things that shouldn\'t be done in CSS Grid, such as a shelf? Bathroom tiles wtf? and makeup palettes. If you are a cultured person, you will have a chance to enjoy a couple of pens inspired by Harry Potter and Pokemon. On the rare occasion that you are looking at this profile for something you can use in production, you really shouldn\'t. But, there are some real-world applications, such as the recipe layout, the product catalog, and color palettes for a style guide.',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-co-grid.jpg',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/collection/DQvYpQ'
                ], [
                    'owner'     => 1,
                    'order'     => 10,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarI-T-C',
                    'decor'     => 'filled',
                    'h1'        => 'Food',
                    'text'      => 'Pies for everyone!' . "\r\n" .
                                   'No man is left behind. There\'s infinite pie with this one div and a repeating background.',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-pie.jpg',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/BaovGmg'
                ], [
                    'owner'     => 1,
                    'order'     => 11,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Frustrated designer runs amok with Captcha ideas',
                    'text'      => 'From Tic Tac Toe to solving meme-based questions, this is a different take on how web captchas should be. "I have not successfully picked out all photos of a truck on the first try. Something\'s gotta change," says the designer, who has requested to remain anonymous.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/RwWdNRd'
                ], [
                    'owner'     => 1,
                    'order'     => 12,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'borderT',
                    'h1'        => 'Slack UI gets reverse engineered',
                    'text'      => 'Another valiant effort to reverse engineer a web app. However, the UI is repurposed to showcase Codepens instead of mock conversations. This is a codepen showcase inception situation.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/GRpvNBa'
                ], [
                    'owner'     => 1,
                    'order'     => 13,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarI-T-C',
                    'decor'     => 'contour',
                    'h1'        => 'Always failing to keep track of your workouts?',
                    'text'      => 'Use this tool!',
                    'image'     => 'media/demo-posts/newspaper/issue-1/showcase-workout.jpg',
                    'image_alt' => '',
                    'credits'   => 'https://codepen.io/oliviale/full/RwWKybY'
                ]
            ]
        ], [
            'id'        => 2,
            'enabled'   => TRUE,
            'language'  => 'en-US',
            'url'       => 'demo-newspaper-issue-2',
            'credits'   => '',
            'edition'   => 'Web Papers demo',
            'slogan'    => 'Gems For Developers',
            'number'    => 'Issue #2',
            'sidebar'   => 'Code Snippets',
            'date'      => '2024-02-01 10:11:12',
            'meta'      => 'Yet another example showing how you can compose sections of a newspaper with a small phrase under the section heading. It also demonstrates how to display source code in a section.',
            'copyright' => '© 2024 A Demo Site',
            'articles'  => [
                [
                    'owner'     => 2,
                    'order'     => 0,
                    'size'      => 'size5x1',
                    'layout'    => 'layoutT-ICCCC',
                    'decor'     => 'borderB',
                    'h1'        => 'HTML: The Bad Parts',
                    'text'      => 'You\'ve probably heard statements along the lines of "HTML is already accessible by default" or "You don\'t need to reinvent this perfectly fine HTML control". I consider these to be more of general claims rather than universal truths. It\'s extremely important for web developers to recognize gaps in the platform. To that end, I\'ve decided to collect a few instances where HTML falls short, through accessibility issues or usability issues.' . "\r\n" .
                                   'This is not a comprehensive list, and it does not include gaps in ARIA. I wanted to find a balance between widely known issues and more frequently encountered (but lesser known) ones, while making sure to include some things that we take for granted. In each section, I will include its severity, alternate suggestions, and links where you can find more detailed information.',
                    'image'     => '',
                    'image_alt' => 'A collection of bad practices in HTML, copied from real websites',
                    'credits'   => 'https://www.htmhell.dev/adventcalendar/2023/13/'
                ], [
                    'owner'     => 2,
                    'order'     => 1,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'borderB',
                    'h1'        => 'KayKit - Dungeon Asset Pack',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-2/kaykit-dungeon.jpg',
                    'image_alt' => 'The Dungeon Pack is a bundle of game assets that contains over 200 stylised 3D assets and characters!',
                    'credits'   => 'https://kaylousberg.itch.io/kaykit-dungeon'
                ], [
                    'owner'     => 2,
                    'order'     => 2,
                    'size'      => 'size1x2',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Naming things needn’t be hard',
                    'text'      => 'The Classnames site provides thematically grouped lists of words. Each word links to a dictionary definition on Wordnik where you can learn more about its meaning, usage and related words.' . "\r\n" .
                                   'All of these lists are licensed under the MIT License.' . "\r\n" .
                                   'Remember, there are only two hard things in computer science: cache invalidation and naming things.',
                    'image'     => '',
                    'image_alt' => 'Find inspiration for naming HTML classes, CSS properties or JS functions using a list of useful words',
                    'credits'   => 'https://classnames.paulrobertlloyd.com/'
                ], [
                    'owner'     => 2,
                    'order'     => 3,
                    'size'      => 'size1x2',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'contour',
                    'h1'        => 'Currently available lists are:',
                    'text'      => 'Action, Collection, Comparison, Numeration, Relation, Nature, Art, Theatre, Music, Architecture, Fashion, Publishing.' . "\r\n" .
                                   'Contributions are welcome.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => ''
                ], [
                    'owner'     => 2,
                    'order'     => 4,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Need a workout?',
                    'text'      => 'Just create a simple project that you like and try to release it. This way you will have a great experience. Enjoy, little bro :)',
                    'image'     => '',
                    'image_alt' => 'Okey, are you ready to start?',
                    'credits'   => ''
                ], [
                    'owner'     => 2,
                    'order'     => 5,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'First advice',
                    'text'      => 'To become well-versed in web development, you need read technical literature about modern programming languages.',
                    'image'     => '',
                    'image_alt' => 'Remember best practices!',
                    'credits'   => ''
                ], [
                    'owner'     => 2,
                    'order'     => 6,
                    'size'      => 'size2x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-2/enduro-atari.png',
                    'image_alt' => 'Enduro - Atari - HTML5 Game by Rafael on Codepen',
                    'credits'   => 'https://codepen.io/rafaelcastrocouto/pen/obQJwb'
                ], [
                    'owner'     => 2,
                    'order'     => 7,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-I-CCC',
                    'decor'     => 'no-decor',
                    'h1'        => 'When a robot sits down at the piano',
                    'text'      => 'AIMatrix RoboMusic is a collection of good results from a non-profit research project to create a music synthesis program using a database of sound samples. The volume of the database used was more than 40 thousand sounds. There was a wide variety of beats, drum lines, synth patterns, bass loops, sound effects, and other categories of samples.' . "\r\n" .
                                   'The idea behind the project was to create a program that would randomly select samples from a database until it found a composition that went well together. The synthesis was carried out without regard to the musical genre. The only condition that had to be met was that, after synthesis, the least amount of human intervention would be required to correct poorly composed sections of the synthesized melody.' . "\r\n" .
                                   'This project existed in eastern Ukraine from 2004 to 2007 and became an unusual phenomenon in the field of artificial intelligence. Without a doubt, such music is inferior to human arrangements. It sounds more monotonous. Don\'t expect anything supernatural from this music. However, you will be surprised how natural some of the synthesized compositions turned out to be.',
                    'image'     => '',
                    'image_alt' => 'А long time ago when computers could compose music...',
                    'credits'   => 'http://music.lib.ru/a/aimatrix_rob/'
                ], [
                    'owner'     => 2,
                    'order'     => 8,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-2/robot-and-piano.jpg',
                    'image_alt' => 'The robot playing piano - photo by Possessed Photography on Unsplash',
                    'credits'   => 'https://unsplash.com/photos/robot-playing-piano-U3sOwViXhkY'
                ], [
                    'owner'     => 2,
                    'order'     => 9,
                    'size'      => 'size5x1',
                    'layout'    => 'layoutT-I-CCCC',
                    'decor'     => 'no-decor',
                    'h1'        => 'What is Mozilla Developer Network?',
                    'text'      => 'MDN Web Docs (formerly Mozilla Developer Network) is an open-source, collaborative project documenting Web platform technologies, including CSS, HTML, JavaScript, and Web APIs. We also provide an extensive set of learning resources for beginning developers and students.' . "\r\n" .
                                   'We\'re always striving to connect developers more seamlessly with the tools and information they need to easily build projects on the open Web. Since our beginnings in 2005, Mozilla and the community have amassed around 45,000 pages of free, open-source content.' . "\r\n" .
                                   'Independent and unbiased - across browsers and technologies. This guiding principle has made MDN Web Docs the go-to repository of independent information for developers, regardless of brand, browser or platform. We are an open community of devs, writers, and other technologists building resources for a better Web, with over 17 million monthly MDN users from all over the world. Anyone can contribute, and each of the 45,000 individuals who have done so over the past decades has strengthened and improved the resource. We also receive content contributions from our partners, including Microsoft, Google, Samsung, Igalia, W3C and others. Together we continue to drive innovation on the Web and serve the common good.' . "\r\n" .
                                   'Accurate and vetted for quality. Through our GitHub documentation repository, contributors can make changes, submit pull requests, have their contributions reviewed and then merged with existing content. Through this workflow, we welcome the vast knowledge and experience of our developer community while maintaining a high level of quality, accurate content.',
                    'image'     => '',
                    'image_alt' => 'MDN\'s mission is to provide a blueprint for a better internet and empower a new generation of developers and content creators to build it',
                    'credits'   => 'https://developer.mozilla.org/en-US/about'
                ], [
                    'owner'     => 2,
                    'order'     => 10,
                    'size'      => 'size1x2',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'coding',
                    'h1'        => 'HTML5 render loop',
                    'text'      => 'let file = "level-1.json";' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'let key = "";' . "\r\n" .
                                   'let map = [];' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'function loadMap ( f ) {' . "\r\n" .
                                   '    let m = ...' . "\r\n" .
                                   '    return m;' . "\r\n" .
                                   '};' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'function getKeyboard () {' . "\r\n" .
                                   '    let k = ...' . "\r\n" .
                                   '    return k;' . "\r\n" .
                                   '};' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'function moveHero ( m, x ) {' . "\r\n" .
                                   '    ...' . "\r\n" .
                                   '};' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'function moveUnits ( m ) {' . "\r\n" .
                                   '    ...' . "\r\n" .
                                   '};' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'function drawScreen () {' . "\r\n" .
                                   '    key = getKeyboard();' . "\r\n" .
                                   '    switch ( key ) {' . "\r\n" .
                                   '        case "esc":' . "\r\n" .
                                   '            return;' . "\r\n" .
                                   '        case "left":' . "\r\n" .
                                   '            moveHero( map, -5 );' . "\r\n" .
                                   '            break;' . "\r\n" .
                                   '        case "right":' . "\r\n" .
                                   '            moveHero( map, 5 );' . "\r\n" .
                                   '            break;' . "\r\n" .
                                   '        default:' . "\r\n" .
                                   '            moveHero( map, 0 );' . "\r\n" .
                                   '    }' . "\r\n" .
                                   '    moveUnits( map );' . "\r\n" .
                                   '    requestAnimationFrame(drawScreen);' . "\r\n" .
                                   '};' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'map = loadMap( file );' . "\r\n" .
                                   'drawScreen();',
                    'image'     => '',
                    'image_alt' => 'How do I draw the game canvas within a loop?',
                    'credits'   => ''
                ], [
                    'owner'     => 2,
                    'order'     => 11,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-2/toothed-toggle.gif',
                    'image_alt' => 'Toothed Toggle - CSS example by Josetxu on Codepen',
                    'credits'   => 'https://codepen.io/josetxu/pen/NWEPmGz'
                ], [
                    'owner'     => 2,
                    'order'     => 12,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'coding',
                    'h1'        => 'CSS variables',
                    'text'      => ':root {' . "\r\n" .
                                   '    --my-var1: red;' . "\r\n" .
                                   '    --my-var2: green;' . "\r\n" .
                                   '    --my-var3: blue;' . "\r\n" .
                                   '}' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'h1 {' . "\r\n" .
                                   '    color: var(--my-var1);' . "\r\n" .
                                   '}' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'h2 {' . "\r\n" .
                                   '    color: var(--my-var2);' . "\r\n" .
                                   '}' . "\r\n" .
                                   ' ' . "\r\n" .
                                   'p {' . "\r\n" .
                                   '    color: var(--my-var3);' . "\r\n" .
                                   '}',
                    'image'     => '',
                    'image_alt' => 'How to use them when you are junior? Let\'s find out.',
                    'credits'   => ''
                ]
            ]
        ], [
            'id'        => 3,
            'enabled'   => TRUE,
            'language'  => 'en-US',
            'url'       => 'demo-newspaper-issue-3',
            'credits'   => '',
            'edition'   => 'Datasets for ML',
            'slogan'    => 'Data For Researchers',
            'number'    => 'Issue #3',
            'sidebar'   => 'Applications',
            'date'      => '2024-04-27 15:27:31',
            'meta'      => 'Where can I get the data? Each of us has asked this question at least once. So, a selection of excellent data resources for your machine learning tasks.',
            'copyright' => '© 2024 A Demo Site',
            'articles'  => [
                [
                    'owner'     => 3,
                    'order'     => 0,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-CI',
                    'decor'     => 'no-decor',
                    'h1'        => 'Awesome Public Datasets',
                    'text'      => 'This is a list of topic-centric public data sources in high quality. They are collected and tidied from blogs, answers, and user responses. Most of the data sets listed below are free, however, some are not. This project was incubated at OMNILab, Shanghai Jiao Tong University during Xiaming Chen\'s Ph.D. studies. OMNILab is now part of the BaiYuLan Open AI community. Other amazingly awesome lists can be found in sindresorhus\'s awesome list.' . "\r\n" .
                                   'Categories are Agriculture, Architecture, Biology, Chemistry, Complex Networks, Computer Networks, Cyber Security, Data Challenges, Earth Science, Economics, Education, Energy, Entertainment, Finance, GIS, Government, Healthcare, Image Processing, Machine Learning, Museums, Natural Language, Neuro Science, Physics, Prostate Cancer, Psychology + Cognition, Public Domains, Search Engines, Social Networks, Social Sciences, Software, Sports, Time Series, Transportation, eSports, Complementary Collections.',
                    'image'     => 'media/demo-posts/newspaper/issue-3/awesome-screenshot.jpg',
                    'image_alt' => 'A topic-centric list of HQ open datasets',
                    'credits'   => 'https://github.com/awesomedata/awesome-public-datasets'
                ], [
                    'owner'     => 3,
                    'order'     => 1,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-I-CC',
                    'decor'     => 'no-decor',
                    'h1'        => 'OpenML Datasets',
                    'text'      => '',
                    'image'     => '',
                    'image_alt' => 'A worldwide machine learning lab',
                    'credits'   => 'https://openml.org/search?type=data'
                ], [
                    'owner'     => 3,
                    'order'     => 2,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-I-CC',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-3/openml-screenshot.jpg',
                    'image_alt' => '',
                    'credits'   => ''
                ], [
                    'owner'     => 3,
                    'order'     => 3,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutT-I-CC',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => 'OpenML allows fine-grained search over thousands of machine learning datasets. Via the website, you can filter by many dataset properties, such as size, type, format, and many more. Via the APIs you have access to many more filters, and you can download a complete table with statistics of all datasest. Via the APIs you can also load datasets directly into your preferred data structures. We are also working on better organization of all datasets by topic.' . "\r\n" .
                                   'Datasets provide training data for machine learning models. OpenML datasets are uniformly formatted and come with rich meta-data to allow automated processing. You can sort or filter them by a range of different properties.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => ''
                ], [
                    'owner'     => 3,
                    'order'     => 4,
                    'size'      => 'size4x1',
                    'layout'    => 'layoutIT-CCC',
                    'decor'     => 'borderT',
                    'h1'        => 'Papers With Code',
                    'text'      => 'Our mission is to create a free and open resource with Machine Learning papers, code, datasets, methods and evaluation tables. We believe this is best done together with the community, supported by NLP and ML.' . "\r\n" .
                                   'All content on this website is openly licenced under CC-BY-SA (same as Wikipedia) and everyone can contribute! We also operate specialized portals for papers with code in astronomy, physics, computer sciences, mathematics and statistics.',
                    'image'     => 'media/demo-posts/newspaper/issue-3/papers-screenshot.jpg',
                    'image_alt' => 'A free resource with all data licensed under CC-BY-SA',
                    'credits'   => 'https://paperswithcode.com/datasets'
                ], [
                    'owner'     => 3,
                    'order'     => 5,
                    'size'      => 'size5x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => '',
                    'text'      => '',
                    'image'     => 'media/demo-posts/newspaper/issue-3/hugging-face.jpg',
                    'image_alt' => 'The AI community building the future',
                    'credits'   => 'https://huggingface.co/datasets'
                ], [
                    'owner'     => 3,
                    'order'     => 6,
                    'size'      => 'size2x1',
                    'layout'    => 'layoutT-I-CC',
                    'decor'     => 'no-decor',
                    'h1'        => 'Registry of Open Data on AWS',
                    'text'      => 'This registry exists to help people discover and share datasets that are available via AWS resources. Here you will find any datasets of these groups: Allen Institute for Artificial Intelligence (AI2), Digital Earth Africa, Data for Good at Meta, NASA Space Act Agreement, NIH STRIDES, NOAA Open Data Dissemination Program, Space Telescope Science Institute, and Amazon Sustainability Data Initiative.',
                    'image'     => '',
                    'image_alt' => 'See all usage examples for datasets listed there',
                    'credits'   => 'https://registry.opendata.aws/'
                ], [
                    'owner'     => 3,
                    'order'     => 7,
                    'size'      => 'size2x1',
                    'layout'    => 'layoutT-I-CC',
                    'decor'     => 'no-decor',
                    'h1'        => 'DagsHub',
                    'text'      => 'Welcome to our Datasets database, where you will find hundreds of datasets from various categories such as computer vision, audio, NLP, and more.' . "\r\n" .
                                   'All datasets are free and ready for use on our platform for all your projects. Browse through our categories and find the perfect dataset to fit your needs. Get started today and experience the power of data.',
                    'image'     => '',
                    'image_alt' => 'Launch your ML development to new heights',
                    'credits'   => 'https://dagshub.com/datasets/'
                ], [
                    'owner'     => 3,
                    'order'     => 8,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'CivitAI models',
                    'text'      => 'It is a platform designed to boost the creation of AI-generated media. We offer an environment where users can upload, share, and discover custom models, each trained on distinct datasets. These models can be leveraged as innovative tools for crafting your creations.',
                    'image'     => '',
                    'image_alt' => 'Find your favorite LoRAs',
                    'credits'   => 'https://civitai.com/models'
                ], [
                    'owner'     => 3,
                    'order'     => 9,
                    'size'      => 'size1x1',
                    'layout'    => 'layoutT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Kaggle Datasets',
                    'text'      => 'Join over 18+ million machine learners to share, stress test, and stay up-to-date on all the latest machine learning techniques and technologies.' . "\r\n" .
                                   'Discover a huge repository of community-published models, data & code for your next project.',
                    'image'     => '',
                    'image_alt' => 'Explore, analyze, and share quality data',
                    'credits'   => 'https://www.kaggle.com/datasets'
                ], [
                    'owner'     => 3,
                    'order'     => 10,
                    'size'      => 'size2x1',
                    'layout'    => 'layoutT-I-CC',
                    'decor'     => 'no-decor',
                    'h1'        => 'Looking for more datasets?',
                    'text'      => 'These datasets are used in machine learning research and have been cited in peer-reviewed academic journals. Datasets are an integral part of the field of machine learning. Major advances in this field can result from advances in learning algorithms (such as deep learning), computer hardware, and, less-intuitively, the availability of high-quality training datasets.' . "\r\n" .
                                   'High-quality labeled training datasets for supervised and semi-supervised machine learning algorithms are usually difficult and expensive to produce because of the large amount of time needed to label the data.',
                    'image'     => '',
                    'image_alt' => 'Okay, please search them through Wikipedia',
                    'credits'   => 'https://en.wikipedia.org/wiki/List_of_datasets_for_machine-learning_research'
                ], [
                    'owner'     => 3,
                    'order'     => 11,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Stable Diffusion',
                    'text'      => 'Stable Diffusion 3, our most advanced image model yet, features the latest in text-to-image technology with greatly improved performance in multi-subject prompts, image quality, and spelling abilities.',
                    'image'     => '',
                    'image_alt' => 'Activating humanity\'s potential through generative AI',
                    'credits'   => 'https://stability.ai/stable-image'
                ], [
                    'owner'     => 3,
                    'order'     => 12,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'MidJourney',
                    'text'      => 'Midjourney is an independent research lab exploring new mediums of thought and expanding the imaginative powers of the human species.' . "\r\n" .
                                   'We are a small self-funded team focused on design, human infrastructure, and AI. We have 11 full-time staff and an incredible set of advisors.',
                    'image'     => '',
                    'image_alt' => '* It is not free application!',
                    'credits'   => 'https://www.midjourney.com/home'
                ], [
                    'owner'     => 3,
                    'order'     => 13,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'DALL·E',
                    'text'      => 'DALL·E 2 is an AI system that can create realistic images and art from a description in natural language.' . "\r\n" .
                                   'It can create original, realistic images and art from a text description. It can combine concepts, attributes, and styles.',
                    'image'     => '',
                    'image_alt' => '* It is not free application!',
                    'credits'   => 'https://openai.com/index/dall-e-2'
                ], [
                    'owner'     => 3,
                    'order'     => 14,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'ComfyUI',
                    'text'      => 'The most powerful and modular stable diffusion GUI, api and backend with a graph/nodes interface.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://github.com/comfyanonymous/ComfyUI'
                ], [
                    'owner'     => 3,
                    'order'     => 15,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Easy Diffusion',
                    'text'      => 'It is a web interface for Stable Diffusion to generate images from text prompts and images. Just enter your text prompt, and see the generated image.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://github.com/easydiffusion/easydiffusion'
                ], [
                    'owner'     => 3,
                    'order'     => 16,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'Automatic1111',
                    'text'      => 'A web interface for Stable Diffusion, implemented using Gradio library.',
                    'image'     => '',
                    'image_alt' => '',
                    'credits'   => 'https://github.com/AUTOMATIC1111/stable-diffusion-webui'
                ], [
                    'owner'     => 3,
                    'order'     => 17,
                    'size'      => 'size1x1',
                    'layout'    => 'sidebarT-I-C',
                    'decor'     => 'no-decor',
                    'h1'        => 'ChatGPT',
                    'text'      => 'Summarize meetings. Generate and debug code. Automate repetitive tasks. Learn new APIs. Learn something new. Dive into a hobby. Answer complex questions.',
                    'image'     => '',
                    'image_alt' => 'Get answers, find inspiration, be more productive',
                    'credits'   => 'https://openai.com/chatgpt'
                ]
            ]
        ]
    ];

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 6: Now you should redefine the property that specifies the full
     *         filename of this module file. Please note that according to
     *         the framework standard, this property must be reinitialized
     *         in the same way in any new node type module. Therefore,
     *         the same line is repeated here as in the base class file
     *         "mimimi.core/NodeWithTable.php".
     *
     * ---------------------------------------------------------------------
     *
     * @access protected
     * @var    string
     *
     * ---------------------------------------------------------------------
     */

    protected $myNodeFile = __FILE__;

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 7: You should overwrite a public method to save the newspaper
     *         entry and attached articles in the database. Please note that
     *         attached articles are located under the "articles" index.
     *
     * ---------------------------------------------------------------------
     *
     * IMPORTANT: This step is optional because we actually used the
     *            "mySaveNewspaper" and "mySaveArticles" routines instead of
     *            the "save" method. Those routines support all the features
     *            of the newspaper editing form and implement the saving of
     *            uploaded images.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   array     $item      The list of columns that need to be saved for the entry.
     * @param   string    $idColumn  (optional) The name of the column containing the entry identifier.
     * @return  int|bool             INTEGER if success, it is identifier of the saved entry.
     *                               FALSE   if failure.
     *
     * ---------------------------------------------------------------------
     */

    public function save ( $item, $idColumn = 'id' ) {

        // save columns corresponding to the newspaper
        $id = parent::save($item, $idColumn);

        // save columns corresponding to attached articles
        if ( $id ) {
            if ( ! empty( $item[ 'articles' ] ) ) {
                foreach ( $item[ 'articles' ] as $row ) {
                    $row[ 'owner' ] = $id;
                    $this->articles->save( $row );
                }
            }
        }

        // return a result
        return $id;
    }

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 8: You should overwrite a public method to install the demo
     *         table rows. The need to overwrite this method is due to the
     *         presence in your web application of a node module with
     *         a primary and secondary table.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   mixed  $params  Some parameters if you need.
     * @return  bool            TRUE  if at least one new row has been added.
     *                          FALSE if the table has not changed.
     *
     * ---------------------------------------------------------------------
     */

    public function install ( $params = null ) {

        // check for presence of secondary table
        $this->articles->install();

        // check for presence of primary table
        return parent::install( $params );
    }

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 9: You should declare and implement a public method to retrieve
     *         a newspaper entry by its URL. Please note that "t1" below is
     *         an alias for the "newspapers" database table.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   string      $url        The relative URL for the newspaper you are looking for.
     * @param   bool        $anyStatus  (optional) TRUE  to retrieve the entry even if it is under moderation.
     *                                             FALSE to get only the enabled entry.
     * @return  array|bool              ARRAY on success. It contains a row obtained from a database table.
     *                                  FALSE on failure. This means the entry you are looking for was not found.
     *
     * ---------------------------------------------------------------------
     */

    public function getItem ( $url, $anyStatus = FALSE ) {

        // build a filter by URL
        $filter = [
            't1.url' => $url
        ];

        // check status
        if ( ! $anyStatus ) {
            $filter[ 't1.enabled' ] = TRUE;
        }

        // find the entry
        $item = $this->select( $filter );

        // attach entries from secondary table
        if ( $item ) {
            $item[ 'articles' ] = $this->articles->getItems( $item[ 'id' ] );
        }

        // return the resulting entry
        return $item;
    }

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 10: Now you should declare and implement a public method to get
     *          all newspaper entries, sorted by descending date. Please
     *          note that "t1" below is an alias for the "newspapers" database
     *          table.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   bool        $anyStatus  (optional) TRUE  to retrieve the entry even if it is under moderation.
     *                                             FALSE to get only the enabled entry.
     * @return  array|bool              ARRAY on success. Each element is an array, like a row obtained from a database table.
     *                                  FALSE on failure. This means no entries were found.
     *
     * ---------------------------------------------------------------------
     */

    public function getItems ( $anyStatus = FALSE ) {

        // build a sorter by date
        $filter = [
            'orderby' => [
                't1.date' => 'desc'
            ]
        ];

        // check status
        if ( ! $anyStatus ) {
            $filter[ 't1.enabled' ] = TRUE;
        }

        // find entries
        return $this->select( $filter, 0, 1000000000 );
    }

    /**
     * ---------------------------------------------------------------------
     *
     * STEP 11: Finally, you should declare and implement a public method to
     *          check for conflict with the same value duplicated in another
     *          entry. Please note that "t1" below is an alias for the
     *          "newspapers" database table.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   string  $by     Column name to search for the value.
     * @param   string  $value  The value of column being tested.
     * @param   int     $id     (optional) The identifier of the news being edited.
     * @return  bool            TRUE  if that value is okay.
     *                          FALSE if a conflict is found.
     *
     * ---------------------------------------------------------------------
     */

    public function testBy ( $by, $value, $id = 0 ) {

        // build filter
        if ( $value ) {
            $filter = [
                't1.' . $by => $value,
                'select'    => [ '1' => 'test' ]
            ];

            // except for the entry with this identifier
            if ( $id ) {
                $filter[ '! t1.id' ] = $id;
            }

            // find entry
            return FALSE == $this->select( $filter );
        }
        return TRUE;
    }
};