<?php
/**
 * -------------------------------------------------------------------------
 *
 * The module to provide specific routines for website themes.
 *
 * -------------------------------------------------------------------------
 *
 * @license  GPL-2.0  https://opensource.org/license/gpl-2-0/
 * @author   MiMiMi Community
 *
 * -------------------------------------------------------------------------
 */

mimimiInclude( 'Helper/Helper.php' );
class MyMimimiHelper extends MimimiModule {
};

/**
 * -------------------------------------------------------------------------
 *
 * Retrieves the next/previous entry relative to the current newspaper.
 *
 *     $row    = entry of the current newspaper
 *     $asNext = TRUE  if you need the next entry
 *     $asNext = FALSE if you need the previuos entry
 *
 * -------------------------------------------------------------------------
 */

function myGetNext ( $row, $asNext = TRUE ) {

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

    // check date
    $filter[ $asNext ? '> t1.date'
                     : '< t1.date' ] = $row[ 'date' ];

    // check status
    global $app;
    $evenModerated = $app->isAdmin( FALSE );
    if ( ! $evenModerated ) {
        $filter[ 't1.enabled' ] = TRUE;
    }

    // find entries
    return $app->newspapers->select( $filter );
};

/**
 * -------------------------------------------------------------------------
 *
 * Retrieves the article text as HTML text.
 *
 *     $row = entry of the article
 *
 * -------------------------------------------------------------------------
 */

function myGetText ( $row ) {
    $html = printValue( $row[ 'text' ], FALSE );
    $html = preg_replace( '~^([ \t]*[\r\n]+)*~u',          '<p>',             $html );
    $html = preg_replace( '~[\s\r\n]*$~u',                 '</p>',            $html );
    $html = preg_replace( '~([\r\n])[ \t]+[\r\n][\r\n]~u', '$1<p>&nbsp;</p>', $html );
    $html = preg_replace( '~[ \t]*[\r\n][\r\n]~u',         '</p><p>',         $html );
    return  preg_replace( '~<p></p>~u',                    '',                $html );
};

/**
 * -------------------------------------------------------------------------
 *
 * Sanitizes the article text.
 *
 *     $text = plain text to be processed
 *
 * -------------------------------------------------------------------------
 */

function mySanitizeText ( $text ) {
    $text = preg_replace( '~^([ \t]*[\r\n]+)+~u', '',      $text );
    $text = preg_replace( '~\s+$~u',              '',      $text );
    $text = preg_replace( '~[\r\n]+~u',           "\r\n",  $text );
    return  preg_replace( '~([ \t]+\r\n)+~u',     " \r\n", $text );
};

/**
 * -------------------------------------------------------------------------
 *
 * Prints the moderating flag for this newspaper.
 *
 *     $row = entry of the newspaper
 *
 * -------------------------------------------------------------------------
 */

function myPrintModerating ( $row ) {
    if ( empty( $row[ 'enabled' ] ) ) {
        printValue(
            myGetSetting( 'marker_moderating' )
        );
    }
};

/**
 * -------------------------------------------------------------------------
 *
 * Retrieves the setting value/listing by its name.
 *
 *     $selected = null         if the setting is a value
 *     $selected = FALSE        if the setting is a list with no selected item
 *     $selected = "some value" if the setting is a list with such an item selected
 *
 * -------------------------------------------------------------------------
 */

function myGetSetting ( $name, $selected = null ) {
    global $app;
    $value = $app->settings->getValue( $name );
    if ( ! is_null( $selected ) ) {
        if ( ! is_array( $value ) ) {
            $value = [ ];
        }
        if ( $selected !== FALSE ) {
            $ok = FALSE;
            foreach ( $value as $item ) {
                if ( $item == $selected ) {
                    $ok = TRUE;
                    break;
                }
            }
            if ( ! $ok ) {
                $value[] = $selected;
            }
        }
    }
    return $value;
};

/**
 * -------------------------------------------------------------------------
 *
 * Prints the setting value by its name.
 *
 * -------------------------------------------------------------------------
 */

function myPrintSetting ( $name ) {
    printValue(
        myGetSetting( $name )
    );
};

/**
 * -------------------------------------------------------------------------
 *
 * Prints the TIMESTAMP value in a human-readable format or for the DATE
 * input box.
 *
 * -------------------------------------------------------------------------
 */

function myPrintDate ( $stamp, $asYYYY_MM_DD = FALSE ) {

    // check the format
    $pattern = '~^(19|20|21)\d\d-' .
                 '(0[1-9]|1[0-2])-' .
                 '(0[1-9]|[1-2]\d|3[0-1])' .
                 '[T\s]?~uis';
    $isValid = preg_match( $pattern, $stamp );
    if ( $isValid ) {

        // extract the date
        $year  = substr( $stamp, 0, 4 );
        $month = substr( $stamp, 5, 2 );
        $day   = substr( $stamp, 8, 2 );

        // if the YYYY-MM-DD format is specified
        if ( $asYYYY_MM_DD ) {
            printValue( $year . '-' . $month . '-' . $day );

        // otherwise
        } else {
            $year  = intval( $year  );
            $month = intval( $month );
            $day   = intval( $day   );

            // calculate the day of week
            $weekday = date( 'w', mktime( 0, 0, 0, $month, $day, $year ) );

            // translate into names
            global $app;
            $list    = $app->settings->getValue( 'month_names' );
            $month   = isset( $list[ $month-1 ] ) ? $list[ $month-1 ]
                                                  : $month;
            $list    = $app->settings->getValue( 'days_of_week' );
            $weekday = isset( $list[ $weekday ] ) ? $list[ $weekday ]
                                                  : $weekday;
            // print the date
            printValue( $weekday . ', ' . $day . ' ' . $month . ', ' . $year );
        }
    }
};

/**
 * -------------------------------------------------------------------------
 *
 * Prints the current date in a human-readable format.
 *
 * -------------------------------------------------------------------------
 */

function myPrintToday () {
    myPrintDate( date( 'Y-m-d' ) );
};

/**
 * -------------------------------------------------------------------------
 *
 * Generates a random URL consisting of 5 parts of 4 characters each.
 *
 * -------------------------------------------------------------------------
 */

function myGenerateUrl () {
    return mimimiRandomId( 4 ) . '-' .
           mimimiRandomId( 4 ) . '-' .
           mimimiRandomId( 4 ) . '-' .
           mimimiRandomId( 4 ) . '-' .
           mimimiRandomId( 4 );
};

/**
 * -------------------------------------------------------------------------
 *
 * Generates an empty row of newspaper article.
 *
 * -------------------------------------------------------------------------
 */

function myGenerateArticle ( $ownerId = 0 ) {
    return [
        'id'        => 0,
        'owner'     => $ownerId,
        'order'     => 0,
        'size'      => 'size5x1',
        'layout'    => 'layoutT-ICCC',
        'decor'     => 'no-decor',
        'h1'        => '',
        'text'      => '',
        'image'     => '',
        'image_alt' => '',
        'credits'   => ''
    ];
};

/**
 * -------------------------------------------------------------------------
 *
 * Generates an empty newspaper row.
 *
 * -------------------------------------------------------------------------
 */

function myGenerateNewspaper () {
    return [
        'id'        => 0,
        'enabled'   => FALSE,
        'language'  => myGetSetting( 'default_language'    ),
        'url'       => myGenerateUrl(),
        'credits'   => myGetSetting( 'default_credits_url' ),
        'edition'   => myGetSetting( 'default_edition'     ),
        'slogan'    => myGetSetting( 'default_slogan'      ),
        'number'    => myGetSetting( 'default_number'      ),
        'sidebar'   => myGetSetting( 'default_sidebar'     ),
        'date'      => date(         'Y-m-d H:i:s'         ),
        'meta'      => '',
        'copyright' => myGetSetting( 'default_copyright'   ),
        'articles'  => [ myGenerateArticle ()              ]
    ];
};

/**
 * -------------------------------------------------------------------------
 *
 * Removes entries of articles attached to the newspaper.
 *
 *     $row           = entry of the newspaper
 *     $excludeIds    = list of article IDs to prevent them from being deleted
 *     $excludeImages = list of image URLs to prevent them from being deleted
 *
 * -------------------------------------------------------------------------
 */

function myRemoveArticles ( $row, $excludeIds = [ ], $excludeImages = [ ] ) {
    global $app;

    // get the newspaper identifier
    $id = empty( $row[ 'id' ] ) ? 0
                                : $row[ 'id' ];

    // delete the articles attached to this newspaper
    if ( $id ) {
        if ( $row[ 'articles' ] ) {
            $ids = [ ];
            foreach ( $row[ 'articles' ] as $item ) {
                $aid = empty( $item[ 'id' ] ) ? 0
                                              : $item[ 'id' ];
                if ( $aid ) {
                    $ok = in_array( $aid, $excludeIds );
                    if ( ! $ok ) {
                        $ids[ ] = $aid;
                    }
                }
            }
            if ( $ids ) {
                $app->newspapers->articles->remove( $ids );

                // delete the images that were attached to the removed articles
                foreach ( $row[ 'articles' ] as $item ) {
                    $aid = empty( $item[ 'id' ] ) ? 0
                                                  : $item[ 'id' ];
                    if ( $aid ) {
                        $ok = in_array( $aid, $excludeIds );
                        if ( ! $ok ) {
                            $url = $item[ 'image' ];
                            if ( $url ) {
                                $ok = in_array( $url, $excludeImages );
                                if ( ! $ok ) {
                                    $ok = $app->newspapers->articles->hasDuplicate( $url, $id );
                                    if ( ! $ok ) {
                                        removeMedia( $url );
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
};

/**
 * -------------------------------------------------------------------------
 *
 * Updates entry of the newspaper.
 *
 *     $oldRow = previous entry of this newspaper
 *     $newRow = edited entry of this newspaper
 *
 * -------------------------------------------------------------------------
 */

function mySaveNewspaper ( & $oldRow, & $newRow ) {
    $id  = empty( $oldRow[ 'id' ] ) ? 0
                                    : $oldRow[ 'id' ];
    $row = [ ];

    // collect only changed columns
    foreach ( $oldRow as $column => & $value ) {
        switch ( $column ) {
            case 'id':
            case 'articles':
                break;
            default:
                if ( $id ) {
                    if ( isset( $newRow[ $column ] ) ) {
                        if ( $newRow[ $column ] != $value ) {
                            $row[ $column ] = $newRow[ $column ];
                        }
                    }
                } else {
                    $row[ $column ] = isset( $newRow[ $column ] ) ? $newRow[ $column ]
                                                                  : $value;
                }
        }
    }

    // if at least one column in the newspaper entry has been changed
    if ( $row ) {

        // save this entry
        global $app;
        $result = $id ? $app->newspapers->update( $id, $row )
                      : $app->newspapers->add   (      $row );

        // save entry ID
        if ( ! $id ) {
            $oldRow[ 'id' ] = $result;
            $newRow[ 'id' ] = $result;
        }
    }
};

/**
 * -------------------------------------------------------------------------
 *
 * Updates entries of articles attached to the newspaper.
 *
 *     $oldRow = previous entry of this newspaper
 *     $newRow = edited entry of this newspaper
 *
 * -------------------------------------------------------------------------
 */

function mySaveArticles ( $oldRow, $newRow ) {
    $id = empty( $oldRow[ 'id' ] ) ? 0
                                   : $oldRow[ 'id' ];

    // scan articles
    if ( $id ) {
        if ( ! empty( $newRow[ 'articles' ] ) ) {
            global $app;
            $valid = [ 'webp',
                       'jpg' ,
                       'jpeg',
                       'png' ,
                       'gif' ,
                       'bmp' ,
                       'svg' ];
            foreach ( $newRow[ 'articles' ] as & $item ) {
                $aid = empty( $item[ 'id' ] ) ? 0
                                              : $item[ 'id' ];
                $row         = [ ];
                $imageOld    = '';
                $imageNew    = '';
                $imageLocal  = '';
                $imageServer = '';

                // find old entry of this article
                $old = [ ];
                if ( $aid ) {
                    foreach ( $oldRow[ 'articles' ] as $temp ) {
                        if ( $temp[ 'id' ] == $aid ) {
                            $old = $temp;
                            break;
                        }
                    }
                }

                // collect only changed columns
                foreach ( $item as $column => & $value ) {
                    switch ( $column ) {

                        // ignore these columns (we'll handle them later)
                        case 'id':
                        case 'owner':
                            break;

                        // the file upload columns will be processed later
                        case 'image_local':
                            $imageLocal = $value;
                            break;
                        case 'image_server':
                            $imageServer = $value;
                            break;

                        // remember the state of the image column
                        case 'image':
                            $imageNew = $value;
                            if ( isset( $old[ $column ] ) ) {
                                $imageOld = $old[ $column ];
                            }

                        // the remaining columns will be collected as usual
                        default:
                            if ( $aid ) {
                                if ( isset( $old[ $column ] ) ) {
                                    if ( $old[ $column ] != $value ) {
                                        $row[ $column ] = $value;
                                    }
                                }
                            } else {
                                $row[ $column ] = $value;
                            }
                    }
                }

                // handle file uploads
                if ( $imageOld ) {
                    if ( $imageOld != $imageNew ) {
                        $ok = $app->newspapers->articles->hasDuplicate( $imageOld, $id );
                        if ( ! $ok ) {
                            removeMedia( $imageOld );
                        }
                    }
                }
                if ( $imageLocal ) {
                    if ( $imageNew ) {
                        uploadMedia( $imageNew, $imageServer, $valid );
                    }
                }

                // if at least one column in the article entry has been changed
                if ( $row ) {
                    $row[ 'owner' ] = $id;

                    // save this entry
                    $aid ? $app->newspapers->articles->update( $aid, $row )
                         : $app->newspapers->articles->add   (       $row );
                }
            }
        }
    }
};
