I'm working on a function to recursively remove arrays and objects recursively. The problem is that certain recursions may be inside private properties of objects.
below is what I tried as well as the entries I tried to use.
this is my entrie
class TestOBJ{
private $fooClosure = null;
public $bar = 5;
private $myPrivateRecursion = null;
private $aimArrayAndContainsRecursion = [];
public function __construct()
{
$this->fooClosure = function(){
echo 'pretty closure';
};
}
public function setMyPrivateRecursion(&$obj){
$this->myPrivateRecursion = &$obj;
}
public function setObjInsideArray(&$obj){
$this->aimArrayAndContainsRecursion[] = &$obj;
}
}
$std = new stdClass();
$std->std = 'any str';
$std->obj = new stdClass();
$std->obj->other = &$std;
$obj = new TestOBJ();
$obj->bar = new TestOBJ();
$obj->bar->bar = 'hey brow, please works';
$obj->bar->setMyPrivateRecursion($std);
my entrie is var $obj
and this is my function / solution
function makeRecursionStack($vector, &$stack = [], $from = null)
{
if ($vector) {
if (is_object($vector) && !in_array($vector, $stack, true) && !is_callable($vector)) {
$stack[] = &$vector;
if (get_class($vector) === 'stdClass') {
foreach ($vector as $key => $value) {
if (in_array($vector->{$key}, $stack, true)) {
$vector->{$key} = null;
} else {
$vector->{$key} = $this->makeRecursionStack($vector->{$key}, $stack, $key);
}
}
return $vector;
} else {
$object = new \ReflectionObject($vector);
$reflection = new \ReflectionClass($vector);
$properties = $reflection->getProperties();
if ($properties) {
foreach ($properties as $property) {
$property = $object->getProperty($property->getName());
$property->setAccessible(true);
if (!is_callable($property->getValue($vector))) {
$private = false;
if ($property->isPrivate()) {
$property->setAccessible(true);
$private = true;
}
if (in_array($property->getValue($vector), $stack, true)) {
$property->setValue($vector, null);
} else {
//if($property->getName() === 'myPrivateRecursion' && $from === 'bar'){
//$get = $property->getValue($vector);
//$set = $this->makeRecursionStack($get, $stack, $property->getName());
//$property->setValue($vector, $set);
//pre_clear_buffer_die($property->getValue($vector));
//}
$property->setValue($vector, $this->makeRecursionStack($property->getValue($vector), $stack, $property->getName()));
}
if ($private) {
$property->setAccessible(false);
}
}
}
}
return $vector;
}
} else if (is_array($vector)) {
$nvector = [];
foreach ($vector as $key => $value) {
$nvector[$key] = $this->makeRecursionStack($value, $stack, $key);
}
return $nvector;
} else {
if (is_object($vector) && !is_callable($vector)) {
return null;
}
}
}
return $vector;
}
The place where I have comments is where I noticed the problem. if the If is not commented there $get would receive a stdClass that has recursion and this works perfectly and $set would receive the stdClass without recursion. In that order.
$get =
$set =
After this lines
$property->setValue($vector, $set);
pre_clear_buffer_die($property->getValue($vector));
i obtain this
I try to put other value like an bool or null inside property and after set the $set but it's not works.
P.S: pre_clear_buffer_die kill php buffer, init other buffer and show var inside a <pre> after exit from script. Is an debugger function.
I want to make a 404 error page on this routing. How can this be done?
index.php
<?php
include 'route.php';
include 'control/about.php';
include 'control/home.php';
include 'control/contact.php';
$route = new route();
$route->add('/', function(){
echo 'Hello, this is home pageeees';
});
$route->add('/about', 'about');
$route->add('/contact', 'contact');
echo '<pre>';
print_r($route);
$route->submit();
?>
route.php
<?php
class route
{
private $_uri = array();
private $_method = array();
/**
*Builds a collection of internal URL's to look for
*#parameter type $uri
*/
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if($method != null){
$this->_method[] = $method;
}
}
/**
*Makes the thing run!
*/
public function submit()
{
$uriGetParam = isset($_GET['uri'])? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value)
{
if(preg_match("#^$value$#",$uriGetParam))
{
if(is_string($this->_method[$key]))
{
$useMethod = $this->_method[$key];
new $useMethod();
}
else
{
call_user_func($this->_method[$key]);
}
}
}
}
}
?>
The regex in mind I would just add $route->add("/.+", function()...); after all your other routes.
Proof: https://3v4l.org/nk5PZ
But you could also program some logic which evaluates custom 404-Pages when not being able to find a correspondig route.
For example:
private $_notFound;
public function submit() {
$uriGetParam = isset($_GET['uri'])? '/' . $_GET['uri'] : '/';
$matched = false;
foreach ($this->_uri as $key => $value) {
if(preg_match("#^$value$#", $uriGetParam)) {
if(is_string($this->_method[$key])) {
$useMethod = $this->_method[$key];
new $useMethod();
} else {
call_user_func($this->_method[$key]);
}
$matched = true;
}
}
if(!$matched) {
if(isset($this->_notFound)) {
if(is_string($this->_notFound)) {
$action = $this->_notFound;
new $action();
} else {
call_user_func($this->_notFound);
}
}
}
}
public function notFound($callback) {
$this->_notFound = $callback;
}
Then you'll have to add the 404-action by $route->notFound(function... or "class");
I am trying to port my web app from laravel 4 to 5 but I am having issues in that one of my model classes is not found.
I have tried to utilize namespacing and have the following my Models which are located locally C:\xampp\htdocs\awsconfig\app\Models
the file which the error appears in looks like
<?php
use App\Models\SecurityGroup;
function from_camel_case($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match)
{
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}
return implode('_', $ret);
}
$resource_types = array();
$resource_types['AWS::EC2::Instance'] = 'EC2Instance';
$resource_types['AWS::EC2::NetworkInterface'] = 'EC2NetworkInterface';
$resource_types['AWS::EC2::VPC'] = 'VPC';
$resource_types['AWS::EC2::Volume'] = 'Volume';
$resource_types['AWS::EC2::SecurityGroup'] = 'SecurityGroup';
$resource_types['AWS::EC2::Subnet'] = 'Subnet';
$resource_types['AWS::EC2::RouteTable'] = 'RouteTable';
$resource_types['AWS::EC2::EIP'] = 'EIP';
$resource_types['AWS::EC2::NetworkAcl'] = 'NetworkAcl';
$resource_types['AWS::EC2::InternetGateway'] = 'InternetGateway';
$accounts = DB::table('aws_account')->get();
$account_list = array();
foreach(glob('../resources/sns messages/*.json') as $filename)
{
//echo $filename;
$data = file_get_contents($filename);
if($data!=null)
{
$decoded=json_decode($data,true);
if(isset($decoded["Message"]))
{
//echo "found message<br>";
$message= json_decode($decoded["Message"]);
if(isset($message->configurationItem))
{
// echo"found cfi<br>";
$insert_array = array();
$cfi = $message->configurationItem;
switch ($cfi->configurationItemStatus)
{
case "ResourceDiscovered":
//echo"found Resource Discovered<br>";
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
$resource->populate($insert_array);
if (!$resource->checkExists())
{
$resource->save();
if(isset($cfi->configuration->tags))
{
foreach ($cfi->configuration->tags as $t )
{
$tag= new Tag;
$tag->resource_type = "instance";
$tag->resource_id = $resource->id;
$tag->key = $t->key;
$tag->value = $t->value;
$tag->save();
/*if(isset($cfi->awsAccountId))
{
foreach ($accounts as $a)
{
$account_list = $a->account_id;
}
if (!in_array($account_id,$account_list))
{
$account_id = new Account;
$account_id->aws_account_id = $cfi->awsAccountId;
$account_list[] = $account_id;
$account_id->save();
}
} */
}
}
}
}
else
{
echo "Creating ".$cfi["resourceType"]." not yet supported<br>";
}
break;
case 'ResourceDeleted':
// echo"found Resource Deleted<br>";
//ITEM DELETED
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
if ($resource->checkExists($cfi->resourceId))
{
$resource->delete();
if( isset($cfi->configuration->tags))
{
foreach ($cfi->configuration->tags as $t )
{
$tag= new Tag;
$tag->resource_type = "instance";
$tag->resource_id = $resource->id;
$tag->key = $t->key;
$tag->value = $t->value;
if ($tag->checkExists($cfi->configuration->tags))
{
$tag->delete();
}
}
}
}
}
else
{
echo "Deleting ".$cfi["resourceType"]." not yet supported<br>";
}
break;
case 'OK':
//echo"found Resource OK<br>";
//ITEM UPDATED
if (array_key_exists($cfi->resourceType, $resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
if ($resource->checkExists($cfi->resourceId))
{
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$update_array[from_camel_case($key)] = $value;
}
}
$resource->populate($update_array);
$resource->save();
}
}
else
{
echo "Updating ".$cfi["resourceType"]." not yet supported<br>";
}
break;
default:
echo "Status ".$cfi['configurationItemStatus']." not yet supported<br>";
break;
}
}
}
}
}
and the corresponding model whose class cannot be found looks like :
<?php namespace App\Models;
use Eloquent;
class SecurityGroup extends Eloquent
{
protected $table = 'security_group';
public $timestamps = false;
protected $guarded = array('id');
public $fields = array('groupId',
'groupName',
'description',
'ownerId'
);
public function checkExists()
{
return self::where('group_id', $this->group_id)->first();
}
public function populate($array)
{
foreach ($array as $k => $v)
{
$this->$k = $v;
}
}
}
I am lost as to what is causing the problem I don't see any typos but then again who knows as always thanks for any help given.
to solve the resource type needs the full namespace declaration
I am creating an application and handling common things in MY_Controller. I am using Message library to display common messages.
Here is MY_Controller.php:
<?php
class MY_Controller extends CI_Controller {
public $data = array();
public $view = TRUE;
public $theme = FALSE;
public $layout = 'default';
protected $redirect;
protected $models = array();
protected $controller_model;
protected $controller_class;
protected $controller_library;
protected $controller_name;
protected $partials = array(
'meta' => 'partials/meta',
'header' => 'partials/header',
'navigation' => 'partials/navigation',
'content' => 'partials/content',
'footer' => 'partials/footer'
);
public function __construct()
{
parent::__construct();
$this->output->enable_profiler(true);
$this->load->helper('inflector');
$this->load->helper('url');
$this->controller_class = $this->router->class;
if(count($this->models)>0)
{
foreach ($this->models as $model)
{
if (file_exists(APPPATH . 'models/' . $model . '.php'))
{
$this->controller_model = $model;
$this->load->model($model);
}
}
}else{
if (file_exists(APPPATH . 'models/' . $this->controller_model . '.php'))
{
$this->load->model($this->controller_model);
}
}
$this->controller_name = $this->router->fetch_class();
$this->action_name = $this->router->fetch_method();
}
public function _remap($method, $parameters)
{
if (method_exists($this, $method))
{
$this->run_filter('before', $parameters);
$return = call_user_func_array(array($this, $method),$parameters);
$this->run_filter('after', $parameters);
}else{
show_404();
}
if($this->theme === TRUE OR $this->theme === '')
{
$this->theme = 'default';
$this->template->set_theme($this->theme);
}else if(strlen($this->theme) > 0){
$this->template->set_theme($this->theme);
}else{
}
if($this->layout === TRUE OR $this->layout === '')
{
$this->layout = 'default';
$this->template->set_layout($this->layout);
}else if(strlen($this->layout) > 0){
$this->template->set_layout($this->layout);
}else{
}
if(isset($this->partials))
{
foreach($this->partials as $key => $value)
{
$this->template->set_partial($key,$value);
}
}
if(isset($this->data) AND count($this->data)>0)
{
foreach($this->data as $key => $value)
{
if(!is_object($value))
{
$this->template->set($key,$value);
}
}
}
if($this->view === TRUE OR $this->view === '')
{
if($this->parse == TRUE)
{
$parse_string = $this->template->build($this->router->method ,'' ,$this->parse);
echo $this->parse($parse_string);
}else{
$this->_call_content($this->router->method);
$this->template->build($this->router->method,array());
}
}else if(strlen($this->view) > 0){
if($this->parse == TRUE){
$parse_string = $this->template->build($this->router->method ,'' ,$this->parse);
echo $this->parse($parse_string);
}else{
$view = $this->view;
$this->_call_content($view);
$this->template->build($view,array());
}
}else{
$checkpoint = $this->session->flashdata('exit');
if($checkpoint){
exit();
}else{
$this->session->set_flashdata('exit',TRUE);
}
$this->redirect();
}
}
public function _call_content($view)
{
$value = $this->load->view($view,$this->data,TRUE);
$this->template->set('content',$value);
}
/* Common Controller Functions */
public function index()
{
$data[$this->controller_model] = $this->{$this->controller_model}->get_all();
$this->data = $data;
$this->view = TRUE;
if($this->input->is_ajax_request() || $this->session->flashdata('ajax')){
$this->layout = FALSE;
}else{
$this->layout = TRUE;
}
}
public function form()
{
if($this->input->is_ajax_request() OR !$this->input->is_ajax_request())
{
$this->load->helper('inflector');
$id = $this->uri->segment(4,0);
if($data = $this->input->post()){
$result = $this->{$this->controller_model}->validate($data);
if($result){
if($id > 0){
}else{
$this->{$this->controller_model}->insert($data);
}
$this->message->set('message','The page has been added successfully.');
$this->view = FALSE;
$this->layout = FALSE;
$this->redirect = "index";
}else{
$this->message->set('message','The Red fields are required');
}
}
$row = $this->{$this->controller_model}->where($id)->get();
$this->data[$module_name]= $row;
}
}
public function delete()
{
$id = $this->uri->segment(3,0);
if($id != 0){
$this->{$this->controller_model}->delete($id);
}
$this->view = FALSE;
$this->layout = FALSE;
}
public function redirect()
{
redirect($this->redirect);
}
public function call_post($data)
{
foreach($data as $key => $row){
$_POST[$key] = $row;
}
}
public function query()
{
echo $this->db->last_query();
}
public function go($data = '')
{
if(isset($data)){
echo '<pre>';
print_r($data);
}else{
echo '<pre>';
print_r($this->data);
}
}
}
/**/
As you can see i am using Phil Sturgeon's template library and i am handling the layout with Jamierumbelow's techniques.
When i set a message on form insertion failure its fine. I can display it in the _remap like this
echo $this->message->display();
In the controller its working finebut when i call it in the partial navigation it does not display the message. What can possibly be the problem. I have tried on the different places in the My_Controller. Its working fine but not in the partial or even i have tried it in the failed form i am loading again.
This is the message library i am using
https://github.com/jeroenvdgulik/codeigniter-message
Here i s my navigation partial
<nav>
<div id = "navigation">
<ul id="menubar">
<li>Home</li>
<li>Downloads</li>
<li>About Us</li>
</ul>
</div>
<div id="breadcrumb">
<div class="breadcrumbs">
<!-- Here i will pull breadcrumbs dynamically-->
</div>
<!--<h3>Dashboard</h3>-->
</div>
<br clear = "all"/>
<div id="message">
<?php
$data['message'] = $message ;
$this->load->view('messages/success',$data);?>
</div>
</nav>
The message library is using session might be flashdata so i think its loosing session data somehow. Although i am using sessions correctly autoloading it.
I have found the issue. It was very simple. I was using the base url in config file as empty
$config['base_url'] = '';
I have to change it like this
$config['base_url'] = 'http://localhost/myproject/';
I need to modify a php search script so that it can handle multiple entries for a single field. The search engine is designed for a real estate website. The current search form allows users to search for houses by selecting a single neighborhood from a dropdown menu. Instead of a dropdown menu, I would like to use a list of checkboxes so that the the user can search for houses in multiple neighborhoods at one time. I have converted all of the dropdown menu items into checkboxes on the HTML side but the PHP script only searches for houses in the last checkbox selected. For example, if I selected: 'Dallas' 'Boston' 'New York' the search engine will only search for houses in New York.
Im new to PHP, so I am a little at a loss as to how to modify this script to handle the behavior I have described:
<?php
require_once(dirname(__FILE__).'/extra_search_fields.php');
//Add Widget for configurable search.
add_action('plugins_loaded',array('DB_CustomSearch_Widget','init'));
class DB_CustomSearch_Widget extends DB_Search_Widget {
function DB_CustomSearch_Widget($params=array()){
DB_CustomSearch_Widget::__construct($params);
}
function __construct($params=array()){
$this->loadTranslations();
parent::__construct(__('Custom Fields ','wp-custom-fields-search'),$params);
add_action('admin_print_scripts', array(&$this,'print_admin_scripts'), 90);
add_action('admin_menu', array(&$this,'plugin_menu'), 90);
add_filter('the_content', array(&$this,'process_tag'),9);
add_shortcode( 'wp-custom-fields-search', array(&$this,'process_shortcode') );
wp_enqueue_script('jquery');
if(version_compare("2.7",$GLOBALS['wp_version'])>0) wp_enqueue_script('dimensions');
}
function init(){
global $CustomSearchFieldStatic;
$CustomSearchFieldStatic['Object'] = new DB_CustomSearch_Widget();
$CustomSearchFieldStatic['Object']->ensureUpToDate();
}
function currentVersion(){
return "0.3.16";
}
function ensureUpToDate(){
$version = $this->getConfig('version');
$latest = $this->currentVersion();
if($version<$latest) $this->upgrade($version,$latest);
}
function upgrade($current,$target){
$options = $this->getConfig();
if(version_compare($current,"0.3")<0){
$config = $this->getDefaultConfig();
$config['name'] = __('Default Preset','wp-custom-fields-search');
$options['preset-default'] = $config;
}
$options['version']=$target;
update_option($this->id,$options);
}
function getInputs($params = false,$visitedPresets=array()){
if(is_array($params)){
$id = $params['widget_id'];
} else {
$id = $params;
}
if($visitedPresets[$id]) return array();
$visitedPresets[$id]=true;
global $CustomSearchFieldStatic;
if(!$CustomSearchFieldStatic['Inputs'][$id]){
$config = $this->getConfig($id);
$inputs = array();
if($config['preset']) $inputs = $this->getInputs($config['preset'],$visitedPresets);
$nonFields = $this->getNonInputFields();
if($config)
foreach($config as $k=>$v){
if(in_array($k,$nonFields)) continue;
if(!(class_exists($v['input']) && class_exists($v['comparison']) && class_exists($v['joiner']))) {
continue;
}
$inputs[] = new CustomSearchField($v);
}
foreach($inputs as $k=>$v){
$inputs[$k]->setIndex($k);
}
$CustomSearchFieldStatic['Inputs'][$id]=$inputs;
}
return $CustomSearchFieldStatic['Inputs'][$id];
}
function getTitle($params){
$config = $this->getConfig($params['widget_id']);
return $config['name'];
}
function form_processPost($post,$old){
unset($post['###TEMPLATE_ID###']);
if(!$post) $post=array('exists'=>1);
return $post;
}
function getDefaultConfig(){
return array('name'=>'Site Search',
1=>array(
'label'=>__('Key Words','wp-custom-fields-search'),
'input'=>'TextField',
'comparison'=>'WordsLikeComparison',
'joiner'=>'PostDataJoiner',
'name'=>'all'
),
2=>array(
'label'=>__('Category','wp-custom-fields-search'),
'input'=>'DropDownField',
'comparison'=>'EqualComparison',
'joiner'=>'CategoryJoiner'
),
);
}
function form_outputForm($values,$pref){
$defaults=$this->getDefaultConfig();
$prefId = preg_replace('/^.*\[([^]]*)\]$/','\\1',$pref);
$this->form_existsInput($pref);
$rand = rand();
?>
<div id='config-template-<?php echo $prefId?>' style='display: none;'>
<?php
$templateDefaults = $defaults[1];
$templateDefaults['label'] = 'Field ###TEMPLATE_ID###';
echo $this->singleFieldHTML($pref,'###TEMPLATE_ID###',$templateDefaults);
?>
</div>
<?php
foreach($this->getClasses('input') as $class=>$desc) {
if(class_exists($class))
$form = new $class();
else $form = false;
if(compat_method_exists($form,'getConfigForm')){
if($form = $form->getConfigForm($pref.'[###TEMPLATE_ID###]',array('name'=>'###TEMPLATE_NAME###'))){
?>
<div id='config-input-templates-<?php echo $class?>-<?php echo $prefId?>' style='display: none;'>
<?php echo $form?>
</div>
<?php }
}
}
?>
<div id='config-form-<?php echo $prefId?>'>
<?php
if(!$values) $values = $defaults;
$maxId=0;
$presets = $this->getPresets();
array_unshift($presets,__('NONE','wp-custom-fields-search'));
?>
<div class='searchform-name-wrapper'><label for='<?php echo $prefId?>[name]'><?php echo __('Search Title','wp-custom-fields-search')?></label><input type='text' class='form-title-input' id='<?php echo $prefId?>[name]' name='<?php echo $pref?>[name]' value='<?php echo $values['name']?>'/></div>
<div class='searchform-preset-wrapper'><label for='<?php echo $prefId?>[preset]'><?php echo __('Use Preset','wp-custom-fields-search')?></label>
<?php
$dd = new AdminDropDown($pref."[preset]",$values['preset'],$presets);
echo $dd->getInput()."</div>";
$nonFields = $this->getNonInputFields();
foreach($values as $id => $val){
$maxId = max($id,$maxId);
if(in_array($id,$nonFields)) continue;
echo "<div id='config-form-$prefId-$id'>".$this->singleFieldHTML($pref,$id,$val)."</div>";
}
?>
</div>
<br/><?php echo __('Add Field','wp-custom-fields-search')?>
<script type='text/javascript'>
CustomSearch.create('<?php echo $prefId?>','<?php echo $maxId?>');
<?php
foreach($this->getClasses('joiner') as $joinerClass=>$desc){
if(compat_method_exists($joinerClass,'getSuggestedFields')){
$options = eval("return $joinerClass::getSuggestedFields();");
$str = '';
foreach($options as $i=>$v){
$k=$i;
if(is_numeric($k)) $k=$v;
$options[$i] = json_encode(array('id'=>$k,'name'=>$v));
}
$str = '['.join(',',$options).']';
echo "CustomSearch.setOptionsFor('$joinerClass',".$str.");\n";
}elseif(eval("return $joinerClass::needsField();")){
echo "CustomSearch.setOptionsFor('$joinerClass',[]);\n";
}
}
?>
</script>
<?php
}
function getNonInputFields(){
return array('exists','name','preset','version');
}
function singleFieldHTML($pref,$id,$values){
$prefId = preg_replace('/^.*\[([^]]*)\]$/','\\1',$pref);
$pref = $pref."[$id]";
$htmlId = $pref."[exists]";
$output = "<input type='hidden' name='$htmlId' value='1'/>";
$titles="<th>".__('Label','wp-custom-fields-search')."</th>";
$inputs="<td><input type='text' name='$pref"."[label]' value='$values[label]' class='form-field-title'/></td><td><a href='#' onClick='return CustomSearch.get(\"$prefId\").toggleOptions(\"$id\");'>".__('Show/Hide Config','wp-custom-fields-search')."</a></td>";
$output.="<table class='form-field-table'><tr>$titles</tr><tr>$inputs</tr></table>";
$output.="<div id='form-field-advancedoptions-$prefId-$id' style='display: none'>";
$inputs='';$titles='';
$titles="<th>".__('Data Field','wp-custom-fields-search')."</th>";
$inputs="<td><div id='form-field-dbname-$prefId-$id' class='form-field-title-div'><input type='text' name='$pref"."[name]' value='$values[name]' class='form-field-title'/></div></td>";
$count=1;
foreach(array('joiner'=>__('Data Type','wp-custom-fields-search'),'comparison'=>__('Compare','wp-custom-fields-search'),'input'=>__('Widget','wp-custom-fields-search')) as $k=>$v){
$dd = new AdminDropDown($pref."[$k]",$values[$k],$this->getClasses($k),array('onChange'=>'CustomSearch.get("'.$prefId.'").updateOptions("'.$id.'","'.$k.'")','css_class'=>"wpcfs-$k"));
$titles="<th>".$v."</th>".$titles;
$inputs="<td>".$dd->getInput()."</td>".$inputs;
if(++$count==2){
$output.="<table class='form-field-table form-class-$k'><tr>$titles</tr><tr>$inputs</tr></table>";
$count=0;
$inputs = $titles='';
}
}
if($titles){
$output.="<table class='form-field-table'><tr>$titles</tr><tr>$inputs</tr></table>";
$inputs = $titles='';
}
$titles.="<th>".__('Numeric','wp-custom-fields-search')."</th><th>".__('Widget Config','wp-custom-fields-search')."</th>";
$inputs.="<td><input type='checkbox' ".($values['numeric']?"checked='true'":"")." name='$pref"."[numeric]'/></td>";
if(class_exists($widgetClass = $values['input'])){
$widget = new $widgetClass();
if(compat_method_exists($widget,'getConfigForm'))
$widgetConfig=$widget->getConfigForm($pref,$values);
}
$inputs.="<td><div id='$this->id"."-$prefId"."-$id"."-widget-config'>$widgetConfig</div></td>";
$output.="<table class='form-field-table'><tr>$titles</tr><tr>$inputs</tr></table>";
$output.="</div>";
$output.="Remove Field";
return "<div class='field-wrapper'>$output</div>";
}
function getRootURL(){
return WP_CONTENT_URL .'/plugins/' . dirname(plugin_basename(__FILE__) ) . '/';
}
function print_admin_scripts($params){
$jsRoot = $this->getRootURL().'js';
$cssRoot = $this->getRootURL().'css';
$scripts = array('Class.js','CustomSearch.js','flexbox/jquery.flexbox.js');
foreach($scripts as $file){
echo "<script src='$jsRoot/$file' ></script>";
}
echo "<link rel='stylesheet' href='$cssRoot/admin.css' >";
echo "<link rel='stylesheet' href='$jsRoot/flexbox/jquery.flexbox.css' >";
}
function getJoiners(){
return $this->getClasses('joiner');
}
function getComparisons(){
return $this->getClasses('comparison');
}
function getInputTypes(){
return $this->getClasses('input');
}
function getClasses($type){
global $CustomSearchFieldStatic;
if(!$CustomSearchFieldStatic['Types']){
$CustomSearchFieldStatic['Types'] = array(
"joiner"=>array(
"PostDataJoiner" =>__( "Post Field",'wp-custom-fields-search'),
"CustomFieldJoiner" =>__( "Custom Field",'wp-custom-fields-search'),
"CategoryJoiner" =>__( "Category",'wp-custom-fields-search'),
"TagJoiner" =>__( "Tag",'wp-custom-fields-search'),
"PostTypeJoiner" =>__( "Post Type",'wp-custom-fields-search'),
),
"input"=>array(
"TextField" =>__( "Text Input",'wp-custom-fields-search'),
"DropDownField" =>__( "Drop Down",'wp-custom-fields-search'),
"RadioButtonField" =>__( "Radio Button",'wp-custom-fields-search'),
"HiddenField" =>__( "Hidden Constant",'wp-custom-fields-search'),
),
"comparison"=>array(
"EqualComparison" =>__( "Equals",'wp-custom-fields-search'),
"LikeComparison" =>__( "Phrase In",'wp-custom-fields-search'),
"WordsLikeComparison" =>__( "Words In",'wp-custom-fields-search'),
"LessThanComparison" =>__( "Less Than",'wp-custom-fields-search'),
"MoreThanComparison" =>__( "More Than",'wp-custom-fields-search'),
"AtMostComparison" =>__( "At Most",'wp-custom-fields-search'),
"AtLeastComparison" =>__( "At Least",'wp-custom-fields-search'),
"RangeComparison" =>__( "Range",'wp-custom-fields-search'),
//TODO: Make this work...
// "NotEqualComparison" =>__( "Not Equal To",'wp-custom-fields-search'),
)
);
$CustomSearchFieldStatic['Types'] = apply_filters('custom_search_get_classes',$CustomSearchFieldStatic['Types']);
}
return $CustomSearchFieldStatic['Types'][$type];
}
function plugin_menu(){
add_options_page('Form Presets','WP Custom Fields Search',8,__FILE__,array(&$this,'presets_form'));
}
function getPresets(){
$presets = array();
foreach(array_keys($config = $this->getConfig()) as $key){
if(strpos($key,'preset-')===0) {
$presets[$key] = $key;
if($name = $config[$key]['name'])
$presets[$key]=$name;
}
}
return $presets;
}
function presets_form(){
$presets=$this->getPresets();
if(!$preset = $_REQUEST['selected-preset']){
$preset = 'preset-default';
}
if(!$presets[$preset]){
$defaults = $this->getDefaultConfig();
$options = $this->getConfig();
$options[$preset] = $defaults;
if($n = $_POST[$this->id][$preset]['name'])
$options[$preset]['name'] = $n;
elseif($preset=='preset-default')
$options[$preset]['name'] = 'Default';
else{
list($junk,$id) = explode("-",$preset);
$options[$preset]['name'] = 'New Preset '.$id;
}
update_option($this->id,$options);
$presets[$preset] = $options[$preset]['name'];
}
if($_POST['delete']){
check_admin_referer($this->id.'-editpreset-'.$preset);
$options = $this->getConfig();
unset($options[$preset]);
unset($presets[$preset]);
update_option($this->id,$options);
list($preset,$name) = each($presets);
}
$index = 1;
while($presets["preset-$index"]) $index++;
$presets["preset-$index"] = __('New Preset','wp-custom-fields-search');
$linkBase = $_SERVER['REQUEST_URI'];
$linkBase = preg_replace("/&?selected-preset=[^&]*(&|$)/",'',$linkBase);
foreach($presets as $key=>$name){
$config = $this->getConfig($key);
if($config && $config['name']) $name=$config['name'];
if(($n = $_POST[$this->id][$key]['name'])&&(!$_POST['delete']))
$name = $n;
$presets[$key]=$name;
}
$plugin=&$this;
ob_start();
wp_nonce_field($this->id.'-editpreset-'.$preset);
$hidden = ob_get_contents();
$hidden.="<input type='hidden' name='selected-preset' value='$preset'>";
$shouldSave = $_POST['selected-preset'] && !$_POST['delete'] && check_admin_referer($this->id.'-editpreset-'.$preset);
ob_end_clean();
include(dirname(__FILE__).'/templates/options.php');
}
function process_tag($content){
$regex = '/\[\s*wp-custom-fields-search\s+(?:([^\]=]+(?:\s+.*)?))?\]/';
return preg_replace_callback($regex, array(&$this, 'generate_from_tag'), $content);
}
function process_shortcode($atts,$content){
return $this->generate_from_tag(array("",$atts['preset']));
}
function generate_from_tag($reMatches){
global $CustomSearchFieldStatic;
ob_start();
$preset=$reMatches[1];
if(!$preset) $preset = 'default';
wp_custom_fields_search($preset);
$form = ob_get_contents();
ob_end_clean();
return $form;
}
}
global $CustomSearchFieldStatic;
$CustomSearchFieldStatic['Inputs'] = array();
$CustomSearchFieldStatic['Types'] = array();
class AdminDropDown extends DropDownField {
function AdminDropDown($name,$value,$options,$params=array()){
AdminDropDown::__construct($name,$value,$options,$params);
}
function __construct($name,$value,$options,$params=array()){
$params['options'] = $options;
$params['id'] = $params['name'];
parent::__construct($params);
$this->name = $name;
$this->value = $value;
}
function getHTMLName(){
return $this->name;
}
function getValue(){
return $this->value;
}
function getInput(){
return parent::getInput($this->name,null);
}
}
if (!function_exists('json_encode'))
{
function json_encode($a=false)
{
if (is_null($a)) return 'null';
if ($a === false) return 'false';
if ($a === true) return 'true';
if (is_scalar($a))
{
if (is_float($a))
{
// Always use "." for floats.
return floatval(str_replace(",", ".", strval($a)));
}
if (is_string($a))
{
static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';
}
else
return $a;
}
$isList = true;
for ($i = 0, reset($a); $i < count($a); $i++, next($a))
{
if (key($a) !== $i)
{
$isList = false;
break;
}
}
$result = array();
if ($isList)
{
foreach ($a as $v) $result[] = json_encode($v);
return '[' . join(',', $result) . ']';
}
else
{
foreach ($a as $k => $v) $result[] = json_encode($k).':'.json_encode($v);
return '{' . join(',', $result) . '}';
}
}
}
function wp_custom_fields_search($presetName='default'){
global $CustomSearchFieldStatic;
if(strpos($presetName,'preset-')!==0) $presetName="preset-$presetName";
$CustomSearchFieldStatic['Object']->renderWidget(array('widget_id'=>$presetName,'noTitle'=>true),array('number'=>$presetName));
}
function compat_method_exists($class,$method){
return method_exists($class,$method) || in_array(strtolower($method),get_class_methods($class));
}
Your needs would require a non-trivial expansion of the plugin with a new input class. You should probably contact the plugin's developer(s) to request the feature or search for another plugin that satisfies your needs.
If you really want to take a crack at it yourself, I suggest putting the plugin aside and rolling your own search form and pushing that input into WP_query(). Here are a few links to get you started on that:
Modifying A Search Template
Working with WP_Query()
Query argument guide