/** Seems nutty, but take two associative arrays of attribute arrays, and * merge them with the above method, only for the given keys * @param type $keys * @param type $arr1 * @param type $arr2 */ function merge_att_arrs($keys, $arr1=[], $arr2 = []) { if (!$keys) return []; if (ne_string($keys)) { return merge_attributes(keyVal($keys,$arr1), keyVal($keys,$arr2)); } $out = []; foreach ($keys as $key) { $out[$key] = merge_attributes(keyVal($key,$arr1), keyVal($key,$arr2)); } return $out; }
public function get_tests($className) { $className = 'App\\Models\\' . $className; $tableName = $className::getTableName(); $keys = keyVal('keys', keyVal($tableName, static::$tablesAndKeys), []); $keyName = keyVal('key_name', keyVal($tableName, static::$tablesAndKeys)); pkdebug("For class [{$className}], keyName: [{$keyName}], keys:", $keys); if (!$keys || !count($keys) || !$keyName) { pkdebug("Get All [{$className}]"); return $className::get(); } else { #Don't return real data return $className::whereNotIn($keyName, $keys)->get(); } }
/** * Wraps/nests an $el as specified by $opts * @param stringable|array $el - text or dom element or array of elements to be wrapped * if array, entire array nested / wrapped as specified by $opts * Example: $this->nest(['<h2>Simple Text</h2>','<h3>H3 Header</h3>'],'section'); * @param string|array $opts - simplest, if just string, wrap $el * Example: $tpp->wrap('Simple Text','section')=>"<div class'section'>Simple Text</div>" * in a div of class $opts - * if $opts array, might have 'tag' key - the rest are html attributes * Example: $opts = ['tag'=>'h2', 'class'=>'site-header',...] * return "<h2 class='site-header'>$el</h2>" * */ public function nest($el, $opts = []) { $ret = new PkTree(); if (is_simple($opts)) { //return $ret->div($el,$opts); $ret->div($el, $opts); return $ret; } if (is_array($opts)) { $tag = keyVal('tag', $opts, 'div'); unset($opts['tag']); //return $ret->$tag($el, $opts); $ret->{$tag}($el, $opts); return $ret->up(); } throw new \Exception("Invalid argument for OPTS: " . print_r($opts, 1)); }
/** For use in Query Forms - makes a full query control * from the field name and comparison type, with $params * * For now, only handle simple _crit, _val comparisons * with $params['basename'] * * @param assoc array $params: * @paramParam: string 'basename' (required): The basename of the field to search - like, * 'annual_income' - will build a criteria select box called "annual_income_crit' * ("<", ">", etc) * and a value input box named 'annual_income_val' * * @paramParam string 'label' (optional, suggested) - the label for the control * * * @return string HTML to make the control */ public static function htmlQueryControl($params=[]) { $basename = $params['basename']; $queryDef = static::getFullQueryDef($basename); //pkdebug("queryDef:", $queryDef); $criteriaSet = keyVal('criteriaSet', $params); if (!$criteriaSet) { $criteriaSet = keyVal('criteriaSet', $queryDef); //pkdebug("criteriaSet:", $criteriaSet); if (!$criteriaSet) { $criteria = keyVal('criteria', $queryDef); if (ne_arrayish($criteria)) { $criteriaSet = keyVal('criteriaSet',$criteria); //pkdebug("criteriaSet:", $criteriaSet); } } if (!$criteriaSet) { #No custom criteriaSet, so default $comptype = keyVal('comptype', $queryDef, 'numeric'); $criteriaSet = PkMatch::getCriteriaSets($comptype); //pkdebug("criteriaSet:", $criteriaSet); } } //pkdebug("criteriaSet:", $criteriaSet); $params['criteriaSet'] = $criteriaSet; /* $fieldDefArr = keyVal('field_defs', $queryDef); if (ne_array($fieldDefArr)) { $fieldNames = array_keys($fieldDefArr); } else { $fieldNames = [$basename.'_crit', $basename.'_val']; } $critName = null; $valName = null; foreach ($fieldNames as $i => $fieldName) { if (removeEndStr($fieldName, '_crit')) { $critName = $fieldName; unset ($fieldNames[$i]); } if (removeEndStr($fieldName, '_val')) { $valName = $fieldName; unset ($fieldNames[$i]); } } * */ $tmpCtl = PkHtmlRenderer::buildQuerySet($params); //pkdebug("TMPCTL: \n$tmpCtl\n"); return PkHtmlRenderer::buildQuerySet($params); //pkdebug("The QueryDef for [ $basename ]:", $fieldDef); }
public function select($name, $list = [], $selected = null, $options = []) { if (is_arrayish($name)) { $name = keyVal('name', $name); $list = keyVal('list', $name, $list); $selected = keyVal('selected', $name, $selected); $options = keyVal('options', $name, $options); } $options = $this->cleanAttributes($options); $selected = $options['selected'] = $this->fieldValueTemplate($name); $options['name'] = keyVal('name', $options, $name); $options['data-selected'] = $selected; return parent::select($name, $list, $selected, $options); }
/** * Make an Ajax clickable component, assuming JS support. * * Makes an arbitrary DOM element that has the data attribute: * <tt>data-pk-ajax-element</tt> * so clicking will automatically perform an AJAX call. * The URL for the call will be in 'data-ajax-url', and so on * @param array|string $options: * In simplest form, $options is a string with the ajax-url to call. * Then just render a button, with content/label $content * If is_array($options), can contain all arguments - * - Normal HTML attributes, plus optionally: * 'params' => [$key1=>$val2, $key2=>$val2,] data param arr for AJAX * * * 'attr-target' => string: 'name of attribute target_to_recieve_response * 'selector-target' => string: The selector that matches this element or child - replace inner HTML with response * 'func-target' => string: The name of the JS function to be called with fn(click_target, data, func_arg) * * 'attr-arg' => mixed - scalar or array use after AJAX to set the named attribute with. * If an array, expect the AJAX return is a key to the array, to get the value * 'selector-arg' => mixed - scalar or array use after AJAX to set the * inner HTML of the matched element with. If array, AJAX return key to the array, to get the value * * 'func-arg' => mixed - scalar or array to be passed to the JS function from this component * * If no targets are set, the return from the AJAX call does nothing * * @param string $tag - the HTML element to make clickable * @param string $content - the content of the HTML element, if it's a content type * * @return \Illuminate\Support\HtmlString */ public function ajaxElement($options = [], $content = null, $ajax_url = null, $tag = 'button') { if (is_string($options)) { $options = ['ajax-url' => $options]; } $options[] = 'data-pk-ajax-element'; $content = keyVal('content', $options, $content); unset($options['content']); $options['data-ajax-url'] = keyVal('ajax-url', $options, $ajax_url); unset($options['ajax-url']); if (empty($options['data-ajax-url'])) { throw new \Exception("No AJAX URL for AJAX Element"); } $tag = keyVal('tag', $options, $tag); if ($tag === 'button') { $options['type'] = keyVal('type', $options, 'button'); } if (empty($options['params'])) { $options['data-ajax-params'] = ''; } else { $options['data-ajax-params'] = http_build_query($options['params']); } unset($options['params']); $options['data-attr-target'] = keyVal('attr-target', $options); unset($options['attr-target']); $options['data-selector-target'] = keyVal('selector-target', $options); unset($options['selector-target']); $options['data-func-target'] = keyVal('func-target', $options); unset($options['func-target']); #JSON encode target-args - but convert empty array to empty obj manually if (array_key_exists('func-arg', $options)) { if ($options['func-arg'] === []) { $options['data-func-arg'] = '{}'; } else { $options['data-func-arg'] = json_encode($options['func-arg']); } unset($options['func-arg']); } #JSON encode target-args - but convert empty array to empty obj manually if (array_key_exists('attr-arg', $options)) { if ($options['attr-arg'] === []) { $options['data-attr-arg'] = '{}'; } else { $options['data-attr-arg'] = json_encode($options['attr-arg']); } unset($options['attr-arg']); } #JSON encode target-args - but convert empty array to empty obj manually if (array_key_exists('selector-arg', $options)) { if ($options['selector-arg'] === []) { $options['data-selector-arg'] = '{}'; } else { $options['data-selector-arg'] = json_encode($options['selector-arg']); } unset($options['selector-arg']); } pkdebug('options', $options); if (PkHtmlRenderer::contentTag($tag)) { return $this->toHtmlString("<{$tag}" . $this->html->attributes($options) . '>' . $content . "</{$tag}>\n"); } if (PkHtmlRenderer::selfClosingTag($tag)) { #Ignore content return $this->toHtmlString("<{$tag}" . $this->html->attributes($options) . ' />'); } throw new PkException("Invalid args to ajaxElement"); }
/** Gets the time difference between 2 dates, using defaults * * @param scalar|array $args: * If scalar, just tries to figure how many years between now and then * If array: * 'from': Required * 'to' : Default: now() * 'units': 'years', * */ public static function timeDifference($args=[]) { if (!$args) return null; if (is_scalar($args)) { $from = new Carbon($args); $to = new Carbon(); } else if (is_array($args)) { if (empty($args['from'])) return null; $from = new Carbon($args['from']); if (!empty($args['to'])) $to = new Carbon($args['to']); else $to = Carbon::now(); } $units = keyVal('units', $args, 'years'); $diffMethod = "diffIn".$units; return $from->$diffMethod($to); }
public function executeActionSet($actionset = null) { if (!$actionset) { $actionset =& $this->actionset; } $result = $this->result; //pkdebug("Result: [$result], actionset:",$actionset); $return = $this->result; /* if (in_array($result,$this->thingstohide)) { $result = null; $this->thingstohide = []; $hideempty = $this->hideempty; $this->hideempty = null; if($hideempty === true) return null; $return = $hideempty; } if (is_array($this->showforboolean)) { $showbool = $this->showforboolean; $this->showforboolean = null; $return = ($result===null) ? keyVal(0,$showbool) : keyVal(1,$showbool); } * */ foreach ($this->actionset as $action) { $args = keyVal('args', $action, []); $action = $action['function']; array_unshift($args, $return); //pkdebug("ARGS", $args, "return [$return], action",$action); $return = call_user_func_array($action, $args); } $this->actionset = []; $this->result = null; return $return; }
'new_item_class' => "pkmvc-button", 'new_item_content' => 'New', ]; $delete_reqclass = ' js btn data-set-delete '; $new_item_reqclass = ' js btn create-new-data-set '; if (!empty($params) && is_array($params)) { $params = array_merge($default_params, $params); } else { $params = $default_params; } $delete_button = "<div class='$delete_reqclass {$params['delete_class']}'>{$params['delete_content']}</div>\n"; $new_item_button = "<div class='$new_item_reqclass {$params['new_item_class']}'>{$params['new_item_content']}</div>\n"; $params['delete_button'] = keyVal('delete_button',$params,$delete_button); $params['new_item_button'] = keyVal('new_item_button',$params,$new_item_button); /** This is simpler (only one level) one-to-many Blade Form Template Container. If the top level model is "Cart" which has many "Items": 1) In the Model definition for Cart, define the standard Eloquent hasMany for $cart->items(), but also set the Cart $load_relations: public static $load_relations = [ 'items' => 'App\Models\Item', ]; 2) Create a template for a single item that takes parameters: $idx, $model ($model instanceOf Item): 'item.blade.php':
public function __get($key) { return keyVal($key, $this->attributes); }
<?php /** Makes a simple generic bs4 grid with a header row * and content row. * @param arrayish $collection * @param arrayish $fieldmap: Associative Array * fieldnames->HeaderTitles * @param arrayish $params - optional params * $titleClass: The Title CSS Class * $valueClass: The Value CSS Class */ if (!isset($params)) $params = []; $titleClass = keyVal('titleClass',$params,'pk-lbl'); $valueClass = keyVal('valueClass',$params,'pk-val'); $cols = count($fieldmap); $colsz = (int)(12/$cols); $titles = []; $fields = []; foreach ($fieldmap as $fieldName => $title) { $fields[]=$fieldName; $titles[]=$title; } ?> <div class='row grid-head-row'> @foreach($titles as $title) <div class='col-md-{{$colsz}} pkl1 grid-head-col {{$titleClass}}'>{!!hpure($title)!!}</div> @endforeach </div> @foreach ($collection as $item) <div class='row grid-data-row'> @foreach($fields as $field) <div class='col-md-{{$colsz}} grid-data-col {{$valueClass}}'>
/** Special handling to reset passwords in a form, then calls parent method */ public function saveRelations(array $arr = []) { if (!$this->authUpdate()) { throw new Exception("Not authorized to update this object"); } ## Check for password reset if (isset($arr['new_password'])) { $new_password = $arr['new_password']; $confirm_password = keyVal('confirm_password', $arr); if ($new_password !== $confirm_password) { $redirback = redirect()->back()->withInput()->with('error_dialog', "Passwords didn't match"); pkdebug("Type of redirback: ", typeOf($redirback)); return $redirback; } //$arr['password'] = $new_password; $this->password = bcrypt($new_password); } return parent::saveRelations($arr); }
/** Takes a scaler as first arg, and unlimited other args (presumably * arrays) and returns the first non-empty value for that key. * @param type $key * @param type $arg1 * @param type $argx */ function firstKeyVal($key, $arg1 = null, $argx = null) { $args = func_get_args(); $key = array_shift($args); foreach ($args as $arg) { $test = keyVal($key, $arg); if ($test) return $test; } return null; }
/** * Return all the tables w. Primary Key name & values, 'owned' by this Model * @staticvar array $tablesAndKeys * @return array: ['table'=>['key_name'=>'id','keys'=>[3,4,6,12]],... */ public function getTablesAndKeys($tablesAndKeys = []) { //static $tablesAndKeys = []; #['table1'=>[$key1,$key2,$key3],'table2'=>[...] $tableName = $this->getTable(); $keydata = keyVal($tableName, $tablesAndKeys, []); $keys = keyVal('keys', $keydata, []); $keyName = $this->getKeyName(); $key = $this->getKey(); if (in_array($key, $keys)) { pkdebug("Leaving: Table: [{$tableName}], Key: [{$key}], tablesAndKeys:", $tablesAndKeys); return $tablesAndKeys; #Hope that takes care of cycles } $relations = array_keys(static::$load_relations); foreach ($relations as $relation) { foreach ($this->{$relation} as $item) { $tablesAndKeys = $item->getTablesAndKeys($tablesAndKeys); //pkdebug("TKS:", $tks); } } $tablesAndKeys[$tableName]['keys'][] = $key; $tablesAndKeys[$tableName]['key_name'] = $keyName; //pkdebug("Leaving TBL: [$tableName]; keyName: [$keyName], key: [$key], keys:",$keys," tablesAndKeys: ",$tablesAndKeys); return $tablesAndKeys; }
/** Generates Bootstrap Dropdown menus - BUT - on click/tourch ONLY IF UA * isMobile() - otherwise, on hover. So if onHover, the menu label can be a * link as well - if on touch, the item below must be the link. * * @param array $items - indexed array of associative arrays of menu items. * Associative Item array: * ['label'=>$label,'url'=>$url, {'liclass'=>$liclass, 'aclass'=>$aclass}], * where liclass & aclass are optional CSS classes on the item. * * NOTE! The first item is required to have an additional key/value: * 'alt_label' - If the menu drops down on touch, the first label won't * be linkable - so the first item after it is the label with the link. * So the first item has the additional optional params 'alt_aclass' & * 'alt_liclass'. * * @param boolean $noleadinglink - default: false. If true, even a hover * drop down will not have a link at first label. * @return HTML string - the dropdown menu. */ public function bsDropMenu(array $items = [], $noleadinglink = false) { #Drop menu maybe dynamically generated, so might be only 0 or 1 item $sz = count($items); if (!$sz) { return ''; } $menu = ''; if ($sz === 1) { $liclass = keyVal('liclass', $items[0]); $url = keyVal('url', $items[0]); $aclass = keyVal('aclass', $items[0]); $label = keyVal('label', $items[0]); $menu .= "<li class='{$liclass}'><a class='{$aclass}' href='{$url}'>\n {$label}\n </a></li>\n "; return $menu; } foreach ($items as $i => $itemArr) { $liclass = keyVal('liclass', $itemArr); $url = keyVal('url', $itemArr); $aclass = keyVal('aclass', $itemArr); $label = keyVal('label', $itemArr); $alt_label = keyVal('alt_label', $itemArr); $alt_aclass = keyVal('alt_aclass', $itemArr); $alt_liclass = keyVal('alt_liclass', $itemArr); if ($i === 0) { #It's the first item if (isMobile() || $noleadinglink) { $droponhover = isMobile() ? '' : ' droponhover '; $menu .= "<li class='dropdown {$droponhover} {$liclass}'>\n <a href='#' class='{$aclass} dropdown-toggle' data-toggle='dropdown'>\n {$label}\n </a>\n <ul class='dropdown-menu'>\n <li class='{$alt_liclass}'><a class='{$alt_aclass}' href='{$url}'>{$alt_label}</a></li>\n "; } else { #Not mobile - drop on hover $menu .= "<li class='dropdown droponhover {$liclass}'>\n <a class='{$aclass}' href='{$url}'>{$label}</a>\n <ul class='dropdown-menu'>\n "; } } else { # Not the first item, so all the same now $menu .= "<li class='{$liclass}'><a class='{$aclass}' href='{$url}'>{$label}</a></li>\n "; } } $menu .= "</ul>\n </li>\n "; return $menu; }
/** Builds a pair of controls: * - a criteria chooser - (like, a select box with '>', '<', etc) * - and a value holder - (typically text box) * - with a label * * @param array $params: There are default values for several settings - * if the input $param value is an array, it is added to the default value; * if it is a string, it replaces the default value. * Example: defaultWrapClass = ' query-set-class ': * if $param['wrapClass'] === ' custom-set-class ', $setClass = ' custom-set-class' * if $param['wrapClass'] === ['custom-set-class'], $setClass = 'query-set-class custom-set-class' * * @paramParam string 'label' - The label for the set * @paramParam string 'wrapTag' - The wrapper type: default: 'fieldset' * @paramParam string 'critVal' - Criteria value - default null * @paramParam string 'valVal' - (comparison) Value value - default null * @paramParam string|array 'wrapClass' - The css class for the set wrapper * @paramParam string|array 'labelClass' - The css class for the set label * @paramParam string|array 'critClass' - The css class for the critBox * @paramParam string|array 'valClass' - The css class for the valBox * @paramParam assoc array 'critAtts' - optional criteria control atts * @paramParam assoc array 'valAtts' - optional value control atts * @paramParam string 'critType' - Default: 'select' * @paramParam string 'valType' - Default: 'text' * @paramParam string 'enabled' - 'enabled', 'disabled', null : Default: null * * #Field Names: - EITHER 'basename' is set, or 'critname' & 'valname' are set. * @paramParam string 'basename': If set, creates * the criteria field "$basename_crit' * the value field "$basename_val' * OTHERWISE: * @paramParam string 'critname': The name of the crit field * @paramParam string 'valname': The name of the crit field * * @paramParam assoc array 'criteriaSet' : crit values => labels * * @return \PkExtensions\PkHtmlRenderer - Representing the HTML for the Query Control */ public function querySet($params = []) { $defaults = ['wrapTag' => 'fieldset', 'wrapClass' => ' form-group block search-crit-val-pair ', 'labelClass' => '', 'critClass' => ' form-control search-crit ', 'valClass' => ' form-control search-val ', 'valAtts' => [], 'critAtts' => [], 'valType' => 'text', 'critType' => 'select', 'label' => '', 'valVal' => null, 'critVal' => null, 'enabled' => null]; $appendableOpts = ['wrapClass', 'labelClass', 'critClass', 'valClass']; $tmpOpts = []; foreach ($appendableOpts as $apOpt) { $tmpOpts[$apOpt] = keyVal($apOpt, $params); if (ne_array($tmpOpts[$apOpt])) { $params[$apOpt] = $defaults[$apOpt] . ' ' . explode(' ', $tmpOpts[$apOpt]); } } $params = array_merge($defaults, $params); $basename = keyVal('basename', $params); $params['critname'] = keyVal('critname', $params, $basename . '_crit'); $params['valname'] = keyVal('valname', $params, $basename . '_val'); $params['critAtts']['class'] = $params['critClass']; unset($params['critClass']); $params['valAtts']['class'] = $params['valClass']; unset($params['valClass']); $wrapTag = $params['wrapTag']; $critType = $params['critType']; $valType = $params['valType']; #Start building! $this->{$wrapTag}(RENDEROPEN, $params['wrapClass']); $this->label(RENDEROPEN, $params['labelClass']); //$this->div($params['label'], $params['labelClass']); $this->rawcontent($params['label']); $this->rawcontent(PkForm::select($params['critname'], $params['criteriaSet'], $params['critVal'], $params['critAtts'])); $this->rawcontent(PkForm::text($params['valname'], $params['valVal'], $params['valAtts'])); $this->RENDERCLOSE(); $this->RENDERCLOSE(); return $this; }
/** Builds an array of image information, and optionally creates compressed versions of them * Checks if the compressed versions exist before re-compressing them. Returns something like: * array: [ 84-Boracay-OurHumbleHomeAfterTyphoon=>[ mimeType=>string:{image/jpeg} file_name=>string:{84-Boracay-OurHumbleHomeAfterTyphoon.jpg} full_path=>string:{C:\www\Laravels\lkirkaas.local\laravel\public\uploads/ORIG_MEDIA/84-Boracay-OurHumbleHomeAfterTyphoon.jpg} url=>string:{http://lkirkaas.local/uploads/ORIG_MEDIA/84-Boracay-OurHumbleHomeAfterTyphoon.jpg} aspect_ratio=>double:{1.5450755601876} root_name=>string:{84-Boracay-OurHumbleHomeAfterTyphoon} description=>string:{Our Humble Cottage on Boracay, after the Typhoon} mimeType_c0=>string:{image/jpeg} file_name_c0=>string:{84-Boracay-OurHumbleHomeAfterTyphoon.jpg} full_path_c0=>string:{C:\www\Laravels\lkirkaas.local\laravel\public\uploads/ORIG_MEDIA-1000-1000//84-Boracay-OurHumbleHomeAfterTyphoon.jpg} url_c0=>string:{http://lkirkaas.local/uploads/ORIG_MEDIA-1000-1000/84-Boracay-OurHumbleHomeAfterTyphoon.jpg} mimeType_c1=>string:{image/jpeg} file_name_c1=>string:{84-Boracay-OurHumbleHomeAfterTyphoon.jpg} full_path_c1=>string:{C:\www\Laravels\lkirkaas.local\laravel\public\uploads/ORIG_MEDIA-256-256//84-Boracay-OurHumbleHomeAfterTyphoon.jpg} url_c1=>string:{http://lkirkaas.local/uploads/ORIG_MEDIA-256-256/84-Boracay-OurHumbleHomeAfterTyphoon.jpg} ] 84-Burma-SchwedegonMonk=>[ * @param int levels=2: How many 'levels' of compressed images. Can be as many as elements in $this->maxwidtharr */ public function buildGalleryArray($levels = null) { if ($levels === null) { $levels = 2; } if ($levels > count($this->maxwidtharr)) { throw new PkException("Too many levels for array of sizes"); } if ($this->maxlevels >= $levels && $this->img_items) { return $this->img_items; } // We've already run; return $this->maxlevels = max($this->maxlevels, $levels); if (!$this->relurl) { $this->relurl = $this->relpath; } if (!$this->maxheightarr) { $this->maxheightarr = $this->maxwidtharr; } $setpath = realpath(public_path() . "/{$this->relpath}") . '/'; $srcdir = $this->srcdir; $fullsrcdir = $setpath . $srcdir . '/'; if (!is_dir($fullsrcdir)) { throw new PkException("The src dir [{$fullsrcdir}] doesn't exist"); } $seturl = url("/") . '/' . $this->relurl . "/"; $origurl = $seturl . $srcdir; //$levelroots = []; $level_items = []; for ($level = 0; $level < $levels; $level++) { if (!keyVal($level, $this->cmpdirs)) { $this->cmpdirs[$level] = $srcdir . '-' . $this->maxwidtharr[$level] . '-' . $this->maxheightarr[$level]; } $reldir = keyVal($level, $this->cmpdirs); $level_items[$level] = []; $tmpfullcmpdir = $setpath . $reldir . '/'; $this->fullcmpdirs[$level] = $tmpfullcmpdir; if (!is_dir($tmpfullcmpdir)) { mkdir($tmpfullcmpdir, 0777, true); } $this->cmpurlroots[$level] = $seturl . $reldir . '/'; $levelentries = scandir($this->fullcmpdirs[$level]); foreach ($levelentries as $entry) { $fullpath = $this->fullcmpdirs[$level] . '/' . $entry; $root_name = substr($entry, 0, strrpos($entry, ".")); if (!($level_item = $this->makeLevelItemArray($level, $fullpath))) { continue; } $level_items[$level][$root_name] = $level_item; } } #Get all the valid image files in the src dir: $entries = scandir($fullsrcdir); $img_items = []; foreach ($entries as $entry) { $fullpath = $fullsrcdir . $entry; if (!($mimeType = isValidImagePath($fullpath))) { continue; } $root_name = substr($entry, 0, strrpos($entry, ".")); $exif = []; try { $exif = @exif_read_data($fullpath); } catch (Exception $e) { error_log("Exception Reading EXIF: " . $e->getMessage()); pkdebug("Exception reading EXIF:", $e); } $img_item = ['mimeType' => $mimeType, 'file_name' => $entry, 'full_path' => $fullpath, 'url' => $origurl . '/' . $entry, 'aspect_ratio' => aspectRatio($fullpath), 'root_name' => $root_name, 'description' => keyVal('ImageDescription', $exif)]; for ($level = 0; $level < $levels; $level++) { //pkdebug("Level: [$level], level_items:", $level_items); if (!in_array($root_name, array_keys($level_items[$level]), 1)) { $level_items[$level][$root_name] = $this->makeLevelItemArray($level, $this->makeReducedImageFile($fullpath, $level)); } $img_item = array_merge($img_item, $level_items[$level][$root_name]); } $img_items[$root_name] = $img_item; } return $this->img_items = $img_items; }
/** * * @param integer $items - if -1, single scalar key, else array of keys * @param array $params - ['first'=>null | int - select from the first N keys * @return scalar|array - single scalar key if $items == -1, else array of $items keys */ public static function randKeys($items = -1, $params = []) { $first = keyVal('first', $params); return PkTestGenerator::randData(static::keys($first), $items); //return PkTestGenerator::randData(static::keys(), $items); }
/** Returns a random SQL Time of Day * * @param array $opts: * 'from' - hour from: default: 8AM * 'to' - hour to: default: 17:00/5PM * 'inc' - incremental minutes: default(max): 30. 0 means only whole hours */ public static function randSqlTime($opts = []) { $from = keyVal('from', $opts, 8); $to = keyVal('to', $opts, 17); $inc = min(keyVal('inc', $opts, 15), 30); $hour = mt_rand($from, $to); if (!$inc) { return "{$hour}:00"; } $inc = max($inc, 10); $rg = 60 / $inc; $mins = mt_rand(0, $rg) * $inc % 60; return "{$hour}:{$mins}"; }
public function processSubmit($opts = null, $inits = null) { if (!$this->ShouldProcessSubmit($opts)) { return null; } if ($this->validationrules) { #Perform validation $this->validate(request(), $this->validationrules, $this->validationmessages, $this->validationcustomattributes); } if ($this->validator) { if ($this->validator->fails()) { $this->throwValidationException(request(), $this->validator); } } #In a POST && met 'shouldProcessSubmit' requirements if ($opts instanceof PkModel) { $pkmodel = $opts; } else { if (is_arrayish($opts)) { #We are processing a submission $customProccessor = keyVal('customProccessor', $opts); if (is_callable($customProccessor)) { $customProccessor($opts, $inits); } $pkmodel = keyVal('pkmodel', $opts); $pkmodels = keyVal('pkmodels', $opts); if ($inits === null) { $inits = keyVal('inits', $opts); } $modelkey = keyVal('modelkey', $opts); } } /* #Processing a POST - what to do? Look at args: if (is_string($pkmodel) && class_exists($pkmodel,1) && is_subclass_of($pkmodel, 'PkExtensions\\Models\\PkModel')) { #It's a PkModel name #So what do we do with that? } */ $data = Request::all(); //pkdebug("POST Data:",$data); //$tpkm = typeOf($pkmodel); //if (!$pkmodel) return false; if ($pkmodel instanceof PkModel) { if (is_array($inits)) { foreach ($inits as $key => $val) { $data[$key] = $val; } } $result = $pkmodel->saveRelations($data); return $result; ############ Okay, after here is insanity ..... but I had something in mind ..... if (!$pkmodels || !is_arrayish($pkmodels)) { if (is_arrayish($pkmodel)) { $pkmodels = $pkmodel; } else { $pkmodels = $opts; } } if ($modelName = $this->isModelSetSubmit()) { #Then we look for a key of 'modelset' in the $data array, which #should have the value of a full model name 'App\Models\Item' #THEN we look for the Model Name Key in the $data - name the #controls by name='App\Models\Item[$idx][id]', etc $modelDataArray = keyValOrDefault($modelName, $data, false); if ($modelDataArray === false) { return false; } if ((!is_arrayish($modelDataArray) || !count($modelDataArray)) && !count($pkmodels)) { return false; } if (!is_subclass_of($modelName, 'PkExtensions\\Models\\PkModel')) { throw new Exception("[{$modelName}] does not extend PkModel"); } #We assume $pkmodels is a collection of the original models, and $modelDataArray #contains whatever changes/additions/deletions. We hand off to the Model #class to manage. return $modelName::updateModels($pkmodels, $modelDataArray); } throw new \Exception("Don't know what to do with pkmodels: " . print_r($pkmodels, 1)); } }
/** Takes packaged HTML for a jQuery dialog, encodes it into an element * data-dialog-encoded attribute, assigns the jQuery class, & returns it, * ready to click on & pop. * @param type $dlg * @param type $args */ public function encodeDlgInEl($dlg, $args = []) { if (!$args) { $args = []; } if (ne_string($args)) { $args = ['class' => $args]; } $defaults = ['class' => 'pkmvc-button', 'content' => 'Click', 'tag' => 'div']; $requiredClass = 'js-dialog-button'; $params = array_merge($defaults, $args); $extraClass = keyVal('extra_class', $params); unset($params['extra_class']); $content = $params['content']; unset($params['content']); $tag = $params['tag']; unset($params['tag']); $atts = merge_attributes($params, "{$requiredClass} {$extraClass}"); $atts['data-dialog-encoded'] = html_encode($dlg); return PkRenderer::$tag($content, $atts); }