RdbExtras.php

<?php

namespace RDB;

trait RdbExtras {

    static public $docs = [
        'connection' => 'https://redbeanphp.com/index.php?p=/connection',
        'rdb-issue' => 'https://gitlab.com/taeluf/php/rdb/-/issues'
    ];

    static public function handleException($callingFunc, $exception){
        static::onException($callingFunc, $exception->getMessage(), $exception);
    }
    static public function str_contains($needle, $haystack){
        return strpos($needle, $haystack)!==false;
    }

    /**
     * Print detailed information regarding known exceptions (& throw it)
     */
    static public function onException($function, $message, $exception){
        $docs = static::$docs;
        $docName = null;
        $userMessage = null;
        switch ($function){
            case "find":
            case "findOne":
                if (static::str_contains('Call to a member function find() on null',$message)
                    ||static::str_contains('Call to a member function findOne() on null',$message)){
                    $userMessage = "The finder is null. You probably didn't connect a database to Redbean.";
                    $docName = 'connection';
                }
                break;

            case "store":
                if (static::str_contains('Array may only contain OODBBeans',$message)){
                    $docName = null;
                    $userMessage = "You added a raw value to an ownParamList[]. You MUST only add beans to these.";
                }
                break;

        }

        if ($userMessage==null){
            $userMessage = "We have no special guidance for this exception. Please open an issue.";
            $docName = 'rdb-issue';
        }

        $userMessage = "\n\n{$userMessage}";
        $url = static::$docs[$docName]??null;
        if ($url!=null)$userMessage .= " -- See {$url}";
        $userMessage .= "\n\n";
        echo $userMessage;

        throw $exception;
    }


    /**
     * Insert a row into the given table using pure sql (no beans involved)
     * @deprecated in favor of insert()
     */
    static public function insertArray(string $table, array $row){
        static::insertArrayRows($table, [$row]);
    }

    /** 
     * Insert a set of rows into the given table using pure sql. (no beans or fancy redbean stuff involved)
     * Execs the sql statement when there are 40 rows to insert. 
     * Not terribly efficient, since it uses multiple INSERT INTO statements
     */
    static public function insertArrayRows(string $table, array $arrayOfRows){
        $rows = $arrayOfRows;

        $statements = [];
        $cols = [];
        $values = [];
        $binds = [];
        $rowIndex = 0;
        $justDidInsert=false;

        foreach ($rows as $row){
            $justDidInsert=false;
            $rowIndex++;
            $values = [];
            $cols = [];
            foreach ($row as $col=>$value){
                if (is_array($value))$value = json_encode($value);
                $binds[':'.$col.$rowIndex] = $value;
                $cols[] = "`{$col}`";
                $values[] = ':'.$col.$rowIndex;
            }
            $colsStr = implode(',',$cols);
            $valuesStr = implode(',',$values);
            $sql = 
            <<<SQL
            INSERT INTO {$table} ($colsStr) 
                
                VALUES ($valuesStr)
            ;
            SQL;
            $statements[] = $sql;

            if ($rowIndex>40){
                echo "\nRunning 40 inserts\n";
                $statementsStr = implode("\n", $statements);
                // echo $statementsStr;
                // exit;
                \RDB::exec($statementsStr, $binds);

                $justDidInsert=true;
                $statements = [];
                $binds = [];
                $rowIndex = 0;
            }
        }
        if (!$justDidInsert){
            $statementsStr = implode("\n", $statements);
            \RDB::exec($statementsStr, $binds);
        }
    }
}