Kohana 3 - Get URLs - kohana

could you help me with following questions.
How do i get the:
absolute/relative current url
http://www.example.com/subdir/controller/action
/subdir/controller/action
absolute/relative application url
http://www.example.com/subdir/
/subdir/
I could of course use native php to get it but i think i should rather use ko3 functions.
Any idea how that works?
Thanks in advance!

Tried to make a controller that outputted them all correctly. Let me know if any of them are off.
class Controller_Info extends Controller
{
public function action_index()
{
$uris = array
(
'page' => array
(
'a' => Request::instance()->uri(),
'b' => URL::base(TRUE, FALSE).Request::instance()->uri(),
'c' => URL::site(Request::instance()->uri()),
'd' => URL::site(Request::instance()->uri(), TRUE),
),
'application' => array
(
'a' => URL::base(),
'b' => URL::base(TRUE, TRUE),
'c' => URL::site(),
'd' => URL::site(NULL, TRUE),
),
);
$this->request->headers['Content-Type'] = 'text/plain';
$this->request->response = print_r($uris, true);
}
public function action_version()
{
$this->request->response = 'Kohana version: '.Kohana::VERSION;
}
public function action_php()
{
phpinfo();
}
}
Outputs this:
Array
(
[page] => Array
(
[a] => info/index
[b] => /kohana/info/index
[c] => /kohana/info/index
[d] => http://localhost/kohana/info/index
)
[application] => Array
(
[a] => /kohana/
[b] => http://localhost/kohana/
[c] => /kohana/
[d] => http://localhost/kohana/
)
)
Technically speaking, it's actually only the first page url that is a real relative url, since all the others either start with / or http://.
Needed to get the url for the current page myself, so decided to extend the url class. Thought I could share it here. Let me know what you think :)
/**
* Extension of the Kohana URL helper class.
*/
class URL extends Kohana_URL
{
/**
* Fetches the URL to the current request uri.
*
* #param bool make absolute url
* #param bool add protocol and domain (ignored if relative url)
* #return string
*/
public static function current($absolute = FALSE, $protocol = FALSE)
{
$url = Request::instance()->uri();
if($absolute === TRUE)
$url = self::site($url, $protocol);
return $url;
}
}
echo URL::current(); // controller/action
echo URL::current(TRUE); // /base_url/controller/action
echo URL::current(TRUE, TRUE); // http://domain/base_url/controller/action

Don't you just mean:
Kohana_Request::detect_uri() ?

Absolute/Relative current URL:
// outputs 'http://www.example.com/subdir/controller/action'
echo URL::site(Request::detect_uri(),true));
// outputs '/subdir/controller/action'
echo URL::site(Request::detect_uri());
Absolute/Relative current application URL:
// outputs 'http://www.example.com/subdir/'
echo URL::site(NULL, TRUE);
// outputs '/subdir/'
echo URL::site();
Hope it helps

Related

Codeigniter Version 4.1.7 Rest API Routing Post method not working

I am using Codeigniter Version 4.1.7.
Where I am implementing Rest API.
In the routes the GET method works,however Post method is not working.
I am testing this using POSTMAN.
URL : http://localhost/myproject/api/add-user
Following is the header
Accept: application/json
Content-Type: application/json
Authorization: Basic xxxxxxxxxxx=
Please check the code below for reference.
Routes.php
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Home');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
$routes->setAutoRoute(false);
/*
* --------------------------------------------------------------------
* Route Definitions
* --------------------------------------------------------------------
*/
// We get a performance increase by specifying the default
// route since we don't have to scan directories.
//$routes->get('/', 'Home::index');
$routes->group("api", ["namespace" => "App\Controllers\Api", "filter" => "basicauth"] , function($routes){
$routes->get("list-users", "ApiController::index");
$routes->post("add-user", "ApiController::create");
});
ApiController.php
app\Controllers\Api\ApiController.php
<?php
namespace App\Controllers\Api;
use CodeIgniter\RESTful\ResourceController;
use App\Models\UsersModel;
class ApiController extends ResourceController
{
/**
* Return an array of resource objects, themselves in array format
*
* #return mixed
*/
public function index()
{
//
$users = new UsersModel();
$response = [
'status' => 200,
"error" => false,
'messages' => 'User list API',
'data' => $users->findAll()
];
return $this->respondCreated($response);
}
/**
* Create a new resource object, from "posted" parameters
*
* #return mixed
*/
public function create()
{
//
$rules = [
'first_name' => 'required|min_length[3]|max_length[20]',
'last_name' => 'required|min_length[3]|max_length[20]',
'email' => 'required|min_length[6]|max_length[50]|valid_email|is_unique[users.email]',
'password' => 'required|min_length[8]|max_length[255]',
'password_confirm' => 'matches[password]',
];
...
...
...
return $this->respondCreated($response);
}
}
Any help would be appreciated.

How do I convert an integer to string in CakePHP?

In my CakePHP app when I try to get data like this:
$this->loadModel('Radio');
$posts = $this->Radio->find('all');
the integers are displayed like strings (in debug) :
'Radio' => array(
'idSong' => '4',
'name' => 'batman',
'title' => 'Batman Theme Song'
),
why? the type is int in the DB. I need integers correctly displayed in my JSON files
Not sure if there's a straightforward solution, but you could change the model data using afterfind
Something like
public function afterFind($results, $primary = false) {
foreach ($results as $key => $val) {
if (isset($val['Radio']['idSong'])) {
$results[$key]['Radio']['idSong'] = (int)$results[$key]['Radio']['idSong'];
}
}
return $results;
}

How to implement a pagination for a search module in Zend Framework 2?

I have a module Search in my ZF2 application. The user fills in a search form out and gets a list of courses.
Now I'm adding the pagination to the module. The paginator is basically working: I can retrieve data over it and the pagination is displayed correctly (pagelinks 1-7 for 70 found courses with the dafault setting 10 items per page).
But it's still not usable. When I click on a pagelink, the form POST data is lost. I know -- it cannot work the way, how I implemented it (see the code below). But I have no idea, how to do it correctly, in order to eep checking the form data and nonetheless be able to use pagination.
That is my code:
Table class Search\Model\CourseTable
class CourseTable {
...
// without pagination
// public function findAllByCriteria(CourseSearchInput $input) {
// with pagination
public function findAllByCriteria(CourseSearchInput $input, $pageNumber) {
...
$select = new Select();
$where = new Where();
$having = new Having();
...
// without pagination
// $resultSet = $this->tableGateway->selectWith($select);
// return $resultSet;
// with pagination
$adapter = new \MyNamespqce\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
$paginator = new \Zend\Paginator\Paginator($adapter);
$paginator->setCurrentPageNumber($pageNumber);
return $paginator;
}
...
}
Search\Controller\SearchController
class SearchController extends AbstractActionController {
public function searchCoursesAction() {
$form = $this->getServiceLocator()->get('Search\Form\CourseSearchForm');
$request = $this->getRequest();
if ($request->isPost()) {
$courseSearchInput = new CourseSearchInput();
$form->setInputFilter($courseSearchInput->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$courseSearchInput->exchangeArray($form->getData());
// without pagination
// $courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
// with pagination
$page = $this->params()->fromRoute('page');
$paginator = $this->getCourseTable()->findAllByCriteria($courseSearchInput, $page);
} else {
$paginator = null;
}
} else {
$paginator = null;
}
return new ViewModel(array(
'form' => $form,
// without pagination
// 'courses' => $courses,
// with pagination
'paginator' => $paginator,
'cities' => ...
));
}
...
}
How to get it working?
I also have the same problem, and I have solved it. But this is not good way. May be the idea will help you.
I solved it as follow: (Search pagination for Zend tutorial album module)
I build two action in controller named "search" and "index".
Whenever the search form submitted, it always post the value to search action. Search action build the url with search parameters, and redirect to index to disply search result.
And when the pagination links clicked, then posted values are passed through url. So whenever index action ask for search parameters, it always get the values in same format.
I defined route as follows:
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order][/search_by/:search_by]',
'constraints' => array(
'action' => '(?!\bpage\b)(?!\border_by\b)(?!\bsearch_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
'page' => '[0-9]+',
'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
'order' => 'ASC|DESC',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
There is a parameter named "search_by", which will keep all search parameters as a json string. This is the point, which is not good I know, but have not find any other way yet.
"Search" action build this string as -
public function searchAction()
{
$request = $this->getRequest();
$url = 'index';
if ($request->isPost()) {
$formdata = (array) $request->getPost();
$search_data = array();
foreach ($formdata as $key => $value) {
if ($key != 'submit') {
if (!empty($value)) {
$search_data[$key] = $value;
}
}
}
if (!empty($search_data)) {
$search_by = json_encode($search_data);
$url .= '/search_by/' . $search_by;
}
}
$this->redirect()->toUrl($url);
}
And next index action decode the string, do necessary action, and also send the json string to view.
public function indexAction() {
$searchform = new AlbumSearchForm();
$searchform->get('submit')->setValue('Search');
$select = new Select();
$order_by = $this->params()->fromRoute('order_by') ?
$this->params()->fromRoute('order_by') : 'id';
$order = $this->params()->fromRoute('order') ?
$this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
$page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
$select->order($order_by . ' ' . $order);
$search_by = $this->params()->fromRoute('search_by') ?
$this->params()->fromRoute('search_by') : '';
$where = new \Zend\Db\Sql\Where();
$formdata = array();
if (!empty($search_by)) {
$formdata = (array) json_decode($search_by);
if (!empty($formdata['artist'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('artist', '%' . $formdata['artist'] . '%')
);
}
if (!empty($formdata['title'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('title', '%' . $formdata['title'] . '%')
);
}
}
if (!empty($where)) {
$select->where($where);
}
$album = $this->getAlbumTable()->fetchAll($select);
$totalRecord = $album->count();
$itemsPerPage = 2;
$album->current();
$paginator = new Paginator(new paginatorIterator($album));
$paginator->setCurrentPageNumber($page)
->setItemCountPerPage($itemsPerPage)
->setPageRange(7);
$searchform->setData($formdata);
return new ViewModel(array(
'search_by' => $search_by,
'order_by' => $order_by,
'order' => $order,
'page' => $page,
'paginator' => $paginator,
'pageAction' => 'album',
'form' => $searchform,
'totalRecord' => $totalRecord
));
}
All the sorting and paging url contain that string.
If you know all the searching paarameters before, then you can define that at route, and pass like the same way without json string. As I have to build a common search, I have build a single string.
Source code for "Album search" is available in git hub at https://github.com/tahmina8765/zf2_search_with_pagination_example.
Live Demo: http://zf2pagination.lifencolor.com/public/album
#Sam & #automatix in the question comments are both right. My suggestion (though I'm looking for a simpler alternative) is to construct a segment route, which covers all of the options that you're likely to need and start with a standard form POST request.
Then, after the request is validated, pass the form data to the paginationControl helper as follows:
$resultsView = new ViewModel(array(
'paginator' => $paginator,
'routeParams' => array_filter($form->getData())
));
Then, in your view template, set the route parameters in the paginationControl view helper:
<?php echo $this->paginationControl($paginator, 'Sliding', 'paginator/default',
array('routeParams' => $routeParams)
) ?>
I've used array_filter here because it's a really simple way of removing any element from the form data that's null, empty or so on. That way you don't pass in extra data that you don't need.

how to index cck field of type text area in solr: drupal6

I've created a cck filed of type textarea with name filed_desc, how do i get this field to index in solr.
i found this article http://acquia.com/blog/understanding-apachesolr-cck-api, i have tried this but it is not indexing the filed, can somebody help.
<?php
// $Id$
/**
* Implementation of hook_apachesolr_cck_fields_alter
*/
function example_apachesolr_cck_fields_alter(&$mappings) {
// either for all CCK of a given field_type and widget option
// 'filefield' is here the CCK field_type. Correlates to $field['field_type']
$mappings['text'] = array(
'text_textarea' => array('callback' => 'example_callback', 'index_type' => 'string'),
);
}
/**
* A function that gets called during indexing.
* #node The current node being indexed
* #fieldname The current field being indexed
*
* #return an array of arrays. Each inner array is a value, and must be
* keyed 'value' => $value
*/
function example_callback($node, $fieldname) {
$fields = array();
foreach ($node->$fieldname as $field) {
// In this case we are indexing the filemime type. While this technically
// makes it possible that we could search for nodes based on the mime type
// of their file fields, the real purpose is to have facet blocks during
// searching.
$fields[] = array('value' => $field['field_desc']);
}
return $fields;
}
?>
I am currently working on adding this in a nice, pretty, generic way. If you really need this working now, take a look at this issue on Drupal.org. My code is currently living at GitHub, though hopefully I can get this included upstream and make a release of it.
Hope that helps!
Per field mapping is easier to control.
alter function:
$mappings['per-field']['field_specialities'] = array(
'index_type' => 'string',
'callback' => 'ge_search_apachesolr_field_specialities_callback'
);
callback:
function ge_search_apachesolr_field_specialities_callback($node, $fieldname)
{
$fields = array();
foreach($node->$fieldname as $field) {
$fields[] = array('value' => $field['value']);
}
return $fields;
}

Drupal: Create custom search

I'm trying to create a custom search but getting stuck.
What I want is to have a dropdownbox so the user can choose where to search in.
These options can mean 1 or more content types.
So if he chooses options A, then the search will look in node-type P,Q,R.
But he may not give those results, but only the uid's which will be then themed to gather specific data for that user.
To make it a little bit clearer, Suppose I want to llok for people. The what I'm searching in is 2 content profile types. But ofcourse you dont want to display those as a result, but a nice picture of the user and some data.
I started with creating a form with a textfield and the dropdown box.
Then, in the submit handler, i created the keys and redirected to another pages with those keys as a tail. This page has been defined in the menu hook, just like how search does it.
After that I want to call hook_view to do the actual search by calling node_search, and give back the results.
Unfortunately, it goes wrong. When i click the Search button, it gives me a 404.
But am I on the right track? Is this the way to create a custom search?
Thx for your help.
Here's the code for some clarity:
<?php
// $Id$
/*
* #file
* Searches on Project, Person, Portfolio or Group.
*/
/**
* returns an array of menu items
* #return array of menu items
*/
function vm_search_menu() {
$subjects = _vm_search_get_subjects();
foreach ($subjects as $name => $description) {
$items['zoek/'. $name .'/%menu_tail'] = array(
'page callback' => 'vm_search_view',
'page arguments' => array($name),
'type' => MENU_LOCAL_TASK,
);
}
return $items;
}
/**
* create a block to put the form into.
* #param $op
* #param $delta
* #param $edit
* #return mixed
*/
function vm_search_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Algemene zoek');
return $blocks;
case 'view':
if (0 == $delta) {
$block['subject'] = t('');
$block['content'] = drupal_get_form('vm_search_general_form');
}
return $block;
}
}
/**
* Define the form.
*/
function vm_search_general_form() {
$subjects = _vm_search_get_subjects();
foreach ($subjects as $key => $subject) {
$options[$key] = $subject['desc'];
}
$form['subjects'] = array(
'#type' => 'select',
'#options' => $options,
'#required' => TRUE,
);
$form['keys'] = array(
'#type' => 'textfield',
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Zoek'),
);
return $form;
}
function vm_search_general_form_submit($form, &$form_state) {
$subjects = _vm_search_get_subjects();
$keys = $form_state['values']['keys']; //the search keys
//the content types to search in
$keys .= ' type:' . implode(',', $subjects[$form_state['values']['subjects']]['types']);
//redirect to the page, where vm_search_view will handle the actual search
$form_state['redirect'] = 'zoek/'. $form_state['values']['subjects'] .'/'. $keys;
}
/**
* Menu callback; presents the search results.
*/
function vm_search_view($type = 'node') {
// Search form submits with POST but redirects to GET. This way we can keep
// the search query URL clean as a whistle:
// search/type/keyword+keyword
if (!isset($_POST['form_id'])) {
if ($type == '') {
// Note: search/node can not be a default tab because it would take on the
// path of its parent (search). It would prevent remembering keywords when
// switching tabs. This is why we drupal_goto to it from the parent instead.
drupal_goto($front_page);
}
$keys = search_get_keys();
// Only perform search if there is non-whitespace search term:
$results = '';
if (trim($keys)) {
// Log the search keys:
watchdog('vm_search', '%keys (#type).', array('%keys' => $keys, '#type' => $type));
// Collect the search results:
$results = node_search('search', $type);
if ($results) {
$results = theme('box', t('Zoek resultaten'), $results);
}
else {
$results = theme('box', t('Je zoek heeft geen resultaten opgeleverd.'));
}
}
}
return $results;
}
/**
* returns array where to look for
* #return array
*/
function _vm_search_get_subjects() {
$subjects['opdracht'] =
array('desc' => t('Opdracht'),
'types' => array('project')
);
$subjects['persoon'] =
array('desc' => t('Persoon'),
'types' => array('types_specialisatie', 'smaak_en_interesses')
);
$subjects['groep'] =
array('desc' => t('Groep'),
'types' => array('Villamedia_groep')
);
$subjects['portfolio'] =
array('desc' => t('Portfolio'),
'types' => array('artikel')
);
return $subjects;
}
To be honest, I haven't seen many people implement hook_search. Most just use Views, or, for advanced things, something like Faceted Search.
Did you consider using either for your current project? Why didn't it work?
you could also use a combination of hook_menu for your results, and db_queries with your custom (and optimized so faster) queries.
For example:
search/%/%
where the arguments could be whatever you need, for example the first one for minimum price, the second price to the maximum price, third for minimal bedrooms... Your url would look always like that:
search/200/400/null/3/ ...
I have used a null, but it could be anything that you prefer to consider this field as empty.
Then, from your select form you have just to redirect following the structure of this url and adding the parameters in its correct place.
It is probalby not the most beautiful way of building a url, but using this technique and hook_theme will allow you to have an unlimited flexibility. I can show you a project where we are using this technique and, I think it looks pretty good :-).
Any comment regarding this would be much aprreciated :-).

Resources