HTTP 302 Code while calling createEnvelope() Docusign - docusignapi

I am trying to integrate Docusign with my website. I am going to use embedded signing. For this, I have used JWT Authentication. After Authentication, I generated access token. With the help of access token I am trying to call createEnvelope('--account_id--', '--envelop_definition--'), but, I am getting HTTP 302 response.
Here is my code
<?php
require_once('../vendor/autoload.php');
require_once('../config/docusignConfiguration.php');
use DocuSign\eSign\Client\ApiClient;
use DocuSign\eSign\Configuration;
class DocumentSigner{
private $jwtUserToken = null;
private $envelope_api = null;
public function getAccessManinderToken(){
if(!$this->jwtUserToken){
$this->jwtUserToken = $this->getJwtUserToken();
}
return $this->jwtUserToken[0]->getAccessToken();
}
private function getJwtUserToken(){
global $DOCUSIGN_CONFIG;
$apiClient = new ApiClient();
$apiClient->getOAuth()->setOAuthBasePath($DOCUSIGN_CONFIG['base_path']);
$jwtToken = $apiClient->requestJWTUserToken(
$DOCUSIGN_CONFIG['client_id'],
$DOCUSIGN_CONFIG['user_id'],
$DOCUSIGN_CONFIG['rsa_key'],
$DOCUSIGN_CONFIG['scope']
);
return $jwtToken;
}
public function make_envelope()
{
$demo_docs_path = '../documents/Sample';
$content_bytes = file_get_contents($demo_docs_path . ".pdf");
$base64_file_content = base64_encode($content_bytes);
# Create the document model
$document = new \DocuSign\eSign\Model\Document([ # create the DocuSign document object
'document_base64' => $base64_file_content,
'name' => 'Example document', # can be different from actual file name
'file_extension' => 'pdf', # many different document types are accepted
'document_id' => 1 # a label used to reference the doc
]);
# Create the signer recipient model
$signer = new \DocuSign\eSign\Model\Signer([ # The signer
'email' => 'check#gmail.com', 'name' => 'Checker Singh',
'recipient_id' => "1", 'routing_order' => "1",
# Setting the client_user_id marks the signer as embedded
'client_user_id' => 1000
]);
# Create a sign_here tab (field on the document)
$sign_here = new \DocuSign\eSign\Model\SignHere([ # DocuSign SignHere field/tab
'anchor_string' => '/sn1/', 'anchor_units' => 'pixels',
'anchor_y_offset' => '10', 'anchor_x_offset' => '20'
]);
# Add the tabs model (including the sign_here tab) to the signer
# The Tabs object wants arrays of the different field/tab types
$signer->settabs(new \DocuSign\eSign\Model\Tabs(['sign_here_tabs' => [$sign_here]]));
# Next, create the top level envelope definition and populate it.
$envelope_definition = new \DocuSign\eSign\Model\EnvelopeDefinition([
'email_subject' => "Please sign this document sent from the PHP SDK",
'documents' => [$document],
# The Recipients object wants arrays for each recipient type
'recipients' => new \DocuSign\eSign\Model\Recipients(['signers' => [$signer]]),
'status' => "sent" # requests that the envelope be created and sent.
]);
return $envelope_definition;
}
public function generate(){
global $DOCUSIGN_CONFIG;
# Create the envelope request object
$envelope_definition = $this->make_envelope();
# Call Envelopes::create API method
# Exceptions will be caught by the calling function
$config = new \DocuSign\eSign\Configuration();
$config->setHost($DOCUSIGN_CONFIG['base_path']);
$config->addDefaultHeader('Authorization', 'Bearer ' . $this->getAccessManinderToken());
$api_client = new \DocuSign\eSign\client\ApiClient($config);
$api_client->getOAuth()->setOAuthBasePath($DOCUSIGN_CONFIG['base_path']);
// var_dump($api_client->getUserInfo($this->getAccessManinderToken()));
$this->envelope_api = new \DocuSign\eSign\Api\EnvelopesApi($api_client);
try{
$results = $this->envelope_api->createEnvelope('23c46058-c4e4-4101-8ddc-8f3f317a6e30', $envelope_definition);
return $envelope_id = $results->getEnvelopeId();
}
catch(DocuSign\eSign\Client\ApiException $e){
var_dump($e);
}
}
}
$documentSigner = new DocumentSigner();
// echo $documentSigner->getAccessToken();
var_dump($documentSigner->generate());
?>

The URL that you have for setHost is the account server which is used for API calls related to authentication. I'm thinking that you'd instead want: https://demo.docusign.net which is the base URL for the eSignature endpoints
(Try that, and if that doesn't work, could you try https://demo.docusign.net/restapi).
In general, it looks like that code may have originally come from example code that DocuSign hosts
Code example links: https://developers.docusign.com/docs/esign-rest-api/how-to/code-launchers/
PHP example:
https://github.com/docusign/code-examples-php/blob/master/src/EG001EmbeddedSigning.php

Related

Two signer issue in docusign embedded signing for same envelope one after another

I'm trying to get 2 user signed with docusign embedded sign. I'm using the example code given by Docusign/github. I'd like that the second user, see that the first user has signed the document so, based ob some explanation here, I try to get the envelope id, when the first signer has signed the document, but i obtain an error. It seems that there is something wrong in the second recipient. Someone would help?
$username_docusign=$config['username_docusign'];
$password_docusign=$config['password_docusign'];
$integrator_key_docusign=$config['integrator_key_docusign'];
$host_docusign=$config['host_docusign'];
// create a new DocuSign configuration and assign host and header(s)
$config = new DocuSign\eSign\Configuration();
$config->setSSLVerification(false);
$config->setHost($host_docusign);
$config->addDefaultHeader("X-DocuSign-Authentication", "{\"Username\":\"" . $username_docusign . "\",\"Password\":\"" . $password_docusign . "\",\"IntegratorKey\":\"" . $integrator_key_docusign . "\"}");
/////////////////////////////////////////////////////////////////////////
// STEP 1: Login() API
/////////////////////////////////////////////////////////////////////////
// instantiate a new docusign api client
$apiClient = new DocuSign\eSign\ApiClient($config);
// we will first make the Login() call which exists in the AuthenticationApi...
$authenticationApi = new DocuSign\eSign\Api\AuthenticationApi($apiClient);
// optional login parameters
$options = new \DocuSign\eSign\Api\AuthenticationApi\LoginOptions();
// call the login() API
$loginInformation = $authenticationApi->login($options);
// parse the login results
if(isset($loginInformation) && count($loginInformation) > 0)
{
// note: defaulting to first account found, user might be a
// member of multiple accounts
$loginAccount = $loginInformation->getLoginAccounts()[0];
if(isset($loginInformation))
{
$accountId = $loginAccount->getAccountId();
if(!empty($accountId))
{
echo "Account ID = $accountId\n";
}
}
}
/////////////////////////////////////////////////////////////////////////
// STEP 2: Create & Send Envelope with Embedded Recipient
/////////////////////////////////////////////////////////////////////////
// set recipient information
$recipientName = "user1";
$recipientEmail = "sanjaydas2390#gmail.com";
// configure the document we want signed
$recipientName2 = "user2";
$recipientEmail2 = "dassanjay5313#gmail.com";
$documentFileName = "hhhh.pdf";
$documentName = "hhhh.pdf";
$demo_docs_path = __DIR__ . '/demo_documents/';
// instantiate a new envelopeApi object
$envelopeApi = new DocuSign\eSign\Api\EnvelopesApi($apiClient);
// Add a document to the envelope
$document = new DocuSign\eSign\Model\Document();
$document->setDocumentBase64(base64_encode(file_get_contents($demo_docs_path . 'World_Wide_Corp_fields.pdf')));
$document->setName($documentName);
$document->setDocumentId("1");
// Create a |SignHere| tab somewhere on the document for the recipient to sign
$signHere = new \DocuSign\eSign\Model\SignHere();
$signHere->setAnchorString("Sign here user1");//here my text in html
$signHere->setAnchorXOffset("3");
$signHere->setAnchorYOffset("0");
$signHere->setAnchorUnits("inches");
$signHere->setPageNumber("1");
$signHere->setRecipientId("1");
// add the signature tab to the envelope's list of tabs
$tabs = new DocuSign\eSign\Model\Tabs();
$tabs->setSignHereTabs(array($signHere));
// add a signer to the envelope
$signer = new \DocuSign\eSign\Model\Signer();
$signer->setEmail($recipientEmail);
$signer->setName($recipientName);
$signer->setRecipientId("1");
$signer->setTabs($tabs);
$signer->setClientUserId('12345');
$signHere2 = new \DocuSign\eSign\Model\SignHere();
$signHere2->setAnchorString("Sign here user2");//here my text in html
$signHere2->setAnchorXOffset("3");
$signHere2->setAnchorYOffset("0");
$signHere2->setAnchorUnits("inches");
$signHere2->setPageNumber("1");
$signHere2->setRecipientId("2");
// add the signature tab to the envelope's list of tabs
$tabs2 = new DocuSign\eSign\Model\Tabs();
$tabs2->setSignHereTabs(array($signHere2));
// add a signer to the envelope
$signer2 = new \DocuSign\eSign\Model\Signer();
$signer2->setEmail($recipientEmail2);
$signer2->setName($recipientName2);
$signer2->setRecipientId("2");
$signer2->setTabs($tabs2);
$signer2->setClientUserId('123456');
// must set this to embed the recipient!
// Add a recipient to sign the document
$recipients = new DocuSign\eSign\Model\Recipients();
$recipients->setSigners(array($signer),array($signer2) );
$envelop_definition = new DocuSign\eSign\Model\EnvelopeDefinition();
$envelop_definition->setEmailSubject("oggetto mail");
// set envelope status to "sent" to immediately send the signature request
$envelop_definition->setStatus("sent");
$envelop_definition->setRecipients($recipients);
$envelop_definition->setDocuments(array($document));
// create and send the envelope! (aka signature request)
$envelop_summary = $envelopeApi->createEnvelope($accountId, $envelop_definition, null);
/////////////////////////////////////////////////////////////////////////
// STEP 3: Request Recipient View (aka signing URL)
/////////////////////////////////////////////////////////////////////////
// instantiate a RecipientViewRequest object
$recipient_view_request = new \DocuSign\eSign\Model\RecipientViewRequest();
// set where the recipient is re-directed once they are done signing
$recipient_view_request->setReturnUrl("http://localhost/docusign/index.php?enevelope=".$envelop_summary->getEnvelopeId());
// configure the embedded signer
if ($_GET['enevelope']=="") {
$recipient_view_request->setUserName($recipientName);
$recipient_view_request->setEmail($recipientEmail);
// must reference the same clientUserId that was set for the recipient when they
// were added to the envelope in step 2
$recipient_view_request->setClientUserId('12345');
// used to indicate on the certificate of completion how the user authenticated
$recipient_view_request->setAuthenticationMethod("email");
// generate the recipient view! (aka embedded signing URL)
$signingView = $envelopeApi->createRecipientView($accountId, $envelop_summary->getEnvelopeId(), $recipient_view_request);
$signurl= $signingView->getUrl();
} else {
$recipient_view_request1 = new \DocuSign\eSign\Model\RecipientViewRequest();
// set where the recipient is re-directed once they are done signing
$recipient_view_request1->setReturnUrl("http://localhost/docusign/index.php?enevelope=100");
$recipient_view_request1->setUserName($recipientName2);
$recipient_view_request1->setEmail($recipientEmail2);
// must reference the same clientUserId that was set for the recipient when they
// were added to the envelope in step 2
$recipient_view_request1->setClientUserId('123456');
// used to indicate on the certificate of completion how the user authenticated
$recipient_view_request1->setAuthenticationMethod("email");
// generate the recipient view! (aka embedded signing URL)
$signingView = $envelopeApi->createRecipientView($accountId, $_GET['enevelope'], $recipient_view_request1);
$signurl= $signingView->getUrl();
}
header('Location: '.$signurl);
First off, not sure what sample code you used, but this code you pasted here is using the old/legacy authentication. I highly recommend you use our modern/new oauth. You can find examples for that in this page - https://developers.docusign.com/esign-rest-api/code-examples.
In terms of having 2 recipients sign sequentially, you would have to use what we call "routing order". If you specify a routingOrder parameter on the recipient, DocuSign would route the envelope based on this number (from low to high). So if your first recipient is "1" and second is "2" then the second recipient would only see the envelope after the first one signed it.
/**
* Creates envelope definition
* Document 1: An HTML document.
* Document 2: A Word .docx document.
* Document 3: A PDF document.
* DocuSign will convert all of the documents to the PDF format.
* The recipients' field tags are placed using <b>anchor</b> strings.
* #param $args parameters for the envelope:
* signer_email, signer_name, signer_client_id
* #return mixed -- returns an envelope definition
*/
private function make_envelope($args)
{
# document 1 (html) has sign here anchor tag **signature_1**
# document 2 (docx) has sign here anchor tag /sn1/
# document 3 (pdf) has sign here anchor tag /sn1/
#
# The envelope has two recipients.
# recipient 1 - signer
# recipient 2 - cc
# The envelope will be sent first to the signer.
# After it is signed, a copy is sent to the cc person.
#
# create the envelope definition
$envelope_definition = new \DocuSign\eSign\Model\EnvelopeDefinition([
'email_subject' => 'Please sign this document set'
]);
$doc1_b64 = base64_encode($this->create_document1($args));
# read files 2 and 3 from a local directory
# The reads could raise an exception if the file is not available!
$demo_docs_path = __DIR__ . '/../public/demo_documents/';
$content_bytes = file_get_contents($demo_docs_path . $GLOBALS['DS_CONFIG']['doc_docx']);
$doc2_b64 = base64_encode($content_bytes);
$content_bytes = file_get_contents($demo_docs_path . $GLOBALS['DS_CONFIG']['doc_pdf']);
$doc3_b64 = base64_encode($content_bytes);
# Create the document models
$document1 = new \DocuSign\eSign\Model\Document([ # create the DocuSign document object
'document_base64' => $doc1_b64,
'name' => 'Order acknowledgement', # can be different from actual file name
'file_extension' => 'html', # many different document types are accepted
'document_id' => '1' # a label used to reference the doc
]);
$document2 = new \DocuSign\eSign\Model\Document([ # create the DocuSign document object
'document_base64' => $doc2_b64,
'name' => 'Battle Plan', # can be different from actual file name
'file_extension' => 'docx', # many different document types are accepted
'document_id' => '2' # a label used to reference the doc
]);
$document3 = new \DocuSign\eSign\Model\Document([ # create the DocuSign document object
'document_base64' => $doc3_b64,
'name' => 'Lorem Ipsum', # can be different from actual file name
'file_extension' => 'pdf', # many different document types are accepted
'document_id' => '3' # a label used to reference the doc
]);
# The order in the docs array determines the order in the envelope
$envelope_definition->setDocuments([$document1, $document2, $document3]);
# Create the signer recipient model
$signer1 = new \DocuSign\eSign\Model\Signer([
'email' => $args['signer_email'], 'name' => $args['signer_name'],
'recipient_id' => "1", 'routing_order' => "1"]);
# routingOrder (lower means earlier) determines the order of deliveries
# to the recipients. Parallel routing order is supported by using the
# same integer as the order for two or more recipients.
# create a cc recipient to receive a copy of the documents
$cc1 = new \DocuSign\eSign\Model\CarbonCopy([
'email' => $args['cc_email'], 'name' => $args['cc_name'],
'recipient_id' => "2", 'routing_order' => "2"]);
# Create signHere fields (also known as tabs) on the documents,
# We're using anchor (autoPlace) positioning
#
# The DocuSign platform searches throughout your envelope's
# documents for matching anchor strings. So the
# signHere2 tab will be used in both document 2 and 3 since they
# use the same anchor string for their "signer 1" tabs.
$sign_here1 = new \DocuSign\eSign\Model\SignHere([
'anchor_string' => '**signature_1**', 'anchor_units' => 'pixels',
'anchor_y_offset' => '10', 'anchor_x_offset' => '20']);
$sign_here2 = new \DocuSign\eSign\Model\SignHere([
'anchor_string' => '/sn1/', 'anchor_units' => 'pixels',
'anchor_y_offset' => '10', 'anchor_x_offset' => '20']);
# Add the tabs model (including the sign_here tabs) to the signer
# The Tabs object wants arrays of the different field/tab types
$signer1->setTabs(new \DocuSign\eSign\Model\Tabs([
'sign_here_tabs' => [$sign_here1, $sign_here2]]));
# Add the recipients to the envelope object
$recipients = new \DocuSign\eSign\Model\Recipients([
'signers' => [$signer1], 'carbon_copies' => [$cc1]]);
$envelope_definition->setRecipients($recipients);
# Request that the envelope be sent by setting |status| to "sent".
# To request that the envelope be created as a draft, set to "created"
$envelope_definition->setStatus($args["status"]);
return $envelope_definition;
}
/**
* Creates a customized html document for the envelope
* #param args $
* #return string -- the html document
*/
private function create_document1($args)
{
return <<< heredoc
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body style="font-family:sans-serif;margin-left:2em;">
<h1 style="font-family: 'Trebuchet MS', Helvetica, sans-serif;
color: darkblue;margin-bottom: 0;">World Wide Corp</h1>
<h2 style="font-family: 'Trebuchet MS', Helvetica, sans-serif;
margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;
color: darkblue;">Order Processing Division</h2>
<h4>Ordered by {$args['signer_name']}</h4>
<p style="margin-top:0em; margin-bottom:0em;">Email: {$args['signer_email']}</p>
<p style="margin-top:0em; margin-bottom:0em;">Copy to: {$args['cc_name']}, {$args['cc_email']}</p>
<p style="margin-top:3em;">
Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. Donut jujubes oat cake jelly-o. Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
</p>
<!-- Note the anchor tag for the signature field is in white. -->
<h3 style="margin-top:3em;">Agreed: <span style="color:white;">**signature_1**/</span></h3>
</body>
</html>
heredoc;
}

Stripe PHP - How do I retrieve the ID of the newly added card?

I would like to allow our customers to add multiple cards to their accounts. So at the checkout, they can select which card to use or add a new one.
I can select the already added card IDs by calling:
$cardid = $customer->sources->data[0]->id;
$cardid = $customer->sources->data[1]->id;
$cardid = $customer->sources->data[2]->id;
etc...
But I need to retrieve the card ID or the newly added card.
//Create Token
try {
$token = \Stripe\Token::create(
array(
"card" => array(
"name" => $_POST['ccname'],
"number" => $_POST['ccnum'],
"exp_month" => $_POST['ccxpm'],
"exp_year" => $_POST['ccxpy'],
"cvc" => $_POST['cccvc'] )
)); }
catch(\Stripe\Error\Card $e) {
$body = $e->getJsonBody();
$err = $body['error'];
$status = $err['message'];
}
// Add new Card to Custid
$customer = \Stripe\Customer::retrieve($_POST['custid']);
$customer->sources->create(
array(
"source" => $token['id']
));
$cardid = $customer->sources->data[]->id; ???
// Charge CustID
$mysum = $_POST['amount']*100;
$charge = \Stripe\Charge::create(array(
'customer' => $customer,
'amount' => $mysum,
'currency' => 'usd',
'card' => $cardid
));
The card creation request will return the newly created card object, so you can simply grab the ID from there:
$new_card = $customer->sources->create(array(
"source" => $token['id']
));
$new_card_id = $new_card->id;
Note that Stripe will validate the card with the issuing bank when adding the new card to the customer, and may return a card_error if the validation fails. You should wrap the card creation request in a try/catch block to handle possible errors.

Amazon Product API: Get top/most selling products

I am trying to lookup API which can give items like Top Products or Top Selling Products in a certain section(Book etc). I try to look for browser Node Section but could not find helpful as such.
I hope this PHP example helps you:
// Your AWS Access Key ID, as taken from the AWS Your Account page
$aws_access_key_id = $key_id;
// Your AWS Secret Key corresponding to the above ID, as taken from the AWS Your Account page
$aws_secret_key = $secret_key;
// The region you are interested in
$endpoint = "webservices.amazon.co.uk";
$uri = "/onca/xml";
$params = array(
"Service" => "AWSECommerceService",
"Operation" => "BrowseNodeLookup",
"AWSAccessKeyId" => "$aws_access_key_id",
"AssociateTag" => "$tag",
"BrowseNodeId" => "$nodeid_uk",
"ResponseGroup" => "TopSellers"
);
// Set current timestamp if not set
if (!isset($params["Timestamp"])) {
$params["Timestamp"] = gmdate('Y-m-d\TH:i:s\Z');
}
// Sort the parameters by key
ksort($params);
$pairs = array();
foreach ($params as $key => $value) {
array_push($pairs, rawurlencode($key)."=".rawurlencode($value));
}
// Generate the canonical query
$canonical_query_string = join("&", $pairs);
// Generate the string to be signed
$string_to_sign = "GET\n".$endpoint."\n".$uri."\n".$canonical_query_string;
// Generate the signature required by the Product Advertising API
$signature = base64_encode(hash_hmac("sha256", $string_to_sign, $aws_secret_key, true));
// Generate the signed URL
$request_url = 'http://'.$endpoint.$uri.'?'.$canonical_query_string.'&Signature='.rawurlencode($signature);
echo "Signed URL: \"".$request_url."\"";

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.

drupal 6 programmatically log user in

I'm trying to log in a user as part of a form submit, but why is the following not working:
$user = db_fetch_object(db_query("SELECT * FROM users WHERE mail = '%s' AND pass = '%s'", $mail, md5($pass)));
if ($user) {
// Authenticate user and log in
$params = array(
'name' => $user->name,
'pass' => trim($user->pass)
);
// Authenticate user
$account = user_authenticate($params);
}
if I dump $user I can see the correct values, but if I dump the account it's empty.
You are passing the hashed password to ´user_authenticate()´, while the function expects the clear password (it will hash it itself indirectly when loading the account via ´user_load()´).
So changing your $params array declaration to
$params = array(
'name' => $user->name,
'pass' => $pass
);
should make your example work.
BTW, you could use user_load() yourself to avoid querying the database directly:
$user = user_load(array('mail' => $mail, 'pass' => trim($pass), 'status' => 1));
(The 'status' => 1 will restrict results to active users - you can leave that out, of course, if you really want to allow log ins to disabled accounts ;)

Resources