I'm trying to create a embedded envelope based on a template. The problem I am having is that in the created envelope the tabs I have created are missing.
I searched around and found the role assignment and used that and still no luck. When I look at the XML the role is the same as the template as well as the routing order and ID.
I tried setting the template so that I can't delete any recipients and I get the error:
Uncaught SoapFault exception: [soap:Client] Required recipient in the template has not been provided. Recipient not satisfied for role, Signer, in template Test Form
Here is my PHP to create and send the envelope, a lot of this is code used from the documentation:
// Get the recipient from a post
$rcp1 = new Recipient(); // First recipient to put in recipient array
$rcp1->UserName = $_POST['Name'];
$rcp1->Email = $_POST['Email'];
$rcp1->Type = RecipientTypeCode::Signer;
$rcp1->ID = "1";
$rcp1->RoutingOrder = 1;
$rcp1->CaptiveInfo = new RecipientCaptiveInfo();
$rcp1->CaptiveInfo->ClientUserId = 1;
$rcp1->RoleName = "Signer";
$rcp1->RequireIDLookup = FALSE;
// Create Role Assignments
$assign = new TemplateReferenceRoleAssignment();
$assign->RecipientID = $rcp1->ID;
$assign->RoleName = $rcp1->RoleName;
// Use a server-side template
$templateRef = new TemplateReference();
$templateRef->TemplateLocation = TemplateLocationCode::Server;
$templateRef->RoleAssignments = $assign;
$templateRef->Template = "****";
// Construct the envelope info
$envInfo = new EnvelopeInformation();
$envInfo->AccountId = $AccountID;
$envInfo->Subject = "This is the Subject";
$envInfo->EmailBlurb = "I have no Idea What a blurb is";
// Send creates draft with all the template info
$createEnvelopeFromTemplatesparams = new CreateEnvelopeFromTemplates();
$createEnvelopeFromTemplatesparams->TemplateReferences = array($templateRef);
$createEnvelopeFromTemplatesparams->Recipients = array($rcp1);
$createEnvelopeFromTemplatesparams->EnvelopeInformation = $envInfo;
$createEnvelopeFromTemplatesparams->ActivateEnvelope = true;
$env = $api->CreateEnvelopeFromTemplates($createEnvelopeFromTemplatesparams);
$envStatus = $env->CreateEnvelopeFromTemplatesResult;
// Construct the recipient token authentication assertion and specify
// ID, start time, method, and domain
$assertion = new RequestRecipientTokenAuthenticationAssertion();
$assertion->AssertionID = guid();
$assertion->AuthenticationInstant = nowXsdDate();
$assertion->AuthenticationMethod = RequestRecipientTokenAuthenticationAssertionAuthenticationMethod::Password;
$assertion->SecurityDomain = "Request Recipient Token Test";
// Construct the URLs based on UserName
$recip = $envStatus->RecipientStatuses->RecipientStatus[0];
$urls = new RequestRecipientTokenClientURLs();
$urlbase = getCallbackURL('pop.php');
$urls->OnSigningComplete = $urlbase . "?event=SignComplete&uname=" . $recip->UserName;
$urls->OnViewingComplete = $urlbase . "?event=ViewComplete&uname=" . $recip->UserName;
$urls->OnCancel = $urlbase . "?event=Cancel&uname=" . $recip->UserName;
$urls->OnDecline = $urlbase . "?event=Decline&uname=" . $recip->UserName;
$urls->OnSessionTimeout = $urlbase . "?event=Timeout&uname=" . $recip->UserName;
$urls->OnTTLExpired = $urlbase . "?event=TTLExpired&uname=" . $recip->UserName;
$urls->OnIdCheckFailed = $urlbase . "?event=IDCheck&uname=" . $recip->UserName;
$urls->OnAccessCodeFailed = $urlbase . "?event=AccesssCode&uname=" . $recip->UserName;
$urls->OnException = $urlbase . "?event=Exception&uname=" . $recip->UserName;
// Send
$requestRecipientTokenparams = new RequestRecipientToken();
$requestRecipientTokenparams->EnvelopeID = $envStatus->EnvelopeID;
$requestRecipientTokenparams->ClientUserID = $recip->ClientUserId;
$requestRecipientTokenparams->Username = $recip->UserName;
$requestRecipientTokenparams->Email = $recip->Email;
$requestRecipientTokenparams->AuthenticationAssertion = $assertion;
$requestRecipientTokenparams->ClientURLs = $urls;
$response = $api->RequestRecipientToken($requestRecipientTokenparams);
$tokenUrl = $response->RequestRecipientTokenResult;
echo '<iframe src="' . $tokenUrl . '" width="100%" height="720px"></iframe>';
This is the recipient info that is returned when I RequestTemplate():
[0] => Recipient Object
(
[ID] => 1
[UserName] =>
[SignerName] =>
[Email] =>
[Type] => Signer
[AccessCode] =>
[AddAccessCodeToEmail] =>
[RequireIDLookup] =>
[IDCheckConfigurationName] =>
[PhoneAuthentication] =>
[SignatureInfo] =>
[CaptiveInfo] =>
[CustomFields] =>
[RoutingOrder] => 1
[IDCheckInformationInput] =>
[AutoNavigation] =>
[RecipientAttachment] =>
[Note] =>
[RoleName] => Signer
[TemplateLocked] =>
[TemplateRequired] => 1
[TemplateAccessCodeRequired] =>
[DefaultRecipient] =>
[SignInEachLocation] =>
)
This might be due to you instatiating the templateRoleAssignments as an object and not an array. Since you're using the SOAP api and not REST have you seen the DocuSign SOAP SDK up on Github? That has sample code and projects for 5 different environments including PHP (PHP, Java, C#, Ruby, and Salesforce):
https://github.com/docusign/DocuSign-eSignature-SDK
Looking at a function defined in the PHP project I see the following:
function createFinalRoleAssignments($recipients) {
$roleAssignments[] = new TemplateReferenceRoleAssignment();
foreach ($recipients as $r) {
$assign = new TemplateReferenceRoleAssignment();
$assign->RecipientID = $r->ID;
$assign->RoleName = $r->RoleName;
array_push($roleAssignments, $assign);
}
// eliminate 0th element
array_shift($roleAssignments);
return $roleAssignments;
}
Notice how $roleAssignments is declared as an array using square brackets [], I have a strong feeling that is causing your error. Try defining your roleAssignments the same way and that will probably work.
Related
I started using the php quickstart to connect and create users. Everything works, but cannot add a second email address.
The help is confusing, and can't find an example.
My code so far:
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Directory($client);
// USER DATA
$userName = 'Test';
$userSurname = 'User';
$userDocument = '12345678';
$userEmail = 'test#mail.com';
$name = new Google_Service_Directory_UserName();
$email = new Google_Service_Directory_UserEmail();
$user = new Google_Service_Directory_User();
// CREATE USER TO INSERT
$name->setGivenName($userName);
$name->setFamilyName($userSurname);
$name->setFullName($userName . ' ' . $userSurname);
$email->setAddress($userEmail);
$email->setType('home');
$user->setName($name);
$user->setHashFunction('SHA-1');
$user->setPassword(hash('sha1', $userDocument));
$user->setPrimaryEmail($userName . '.' . $userSurname . '#domain.com');
$user->setSuspended(false);
$user->setChangePasswordAtNextLogin(true);
$user->setEmails(array('address' => 'test#mail.com', 'type' => 'home', 'customType' => '', 'primary' => false)); // don't work
// $user->setEmails($email); // don't work either
$user->setOrgUnitPath('/org/path');
try
{
$createUserResult = $service->users->insert($user);
}
I find the error. The setEmails method receives an multidimensional array, so:
$user->setEmails(array(array('address' => 'test#mail.com', 'type' => 'home', 'customType' => '', 'primary' => false)));
I'm trying to add new users to moodle 3.2 using a REST web service, and i want to customize thees fields (phone1, department, institution) in the student profile.
I used this code
$token = 'a38805c00f33023f7854d5adc720c7a7';
$domainname = 'http://localhost/moodle';
$functionname = 'core_user_create_users';
$restformat = 'json';
$user2 = new stdClass();
$user2->username = strtolower( $rsnew['Serial']);
$user2->password = $rsnew['pass'];
$user2->firstname = $rsnew['Fname'];
$user2->lastname = $rsnew['Lname'];
$user2->email = $rsnew['Email'];
$user2->lang = 'en';
$user2->auth = 'manual';
$user2->country = $rsnew['Country'];
$user2->timezone = '99';
$user2->phone1 = $rsnew['phone'];
$user2->department = $rsnew['dept'];
$user2->institution = $rsnew['branch'];
$user2->idnumber = $rsnew['grade'];
$users = array($user2);
$params = array('users' => $users);
$serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$functionname;
require_once('./curl.php');
$curl = new curl;
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
But i get this error :
{
"exception": "invalid_parameter_exception",
"errorcode": "invalidparameter",
"message": "Invalid parameter value detected",
"debuginfo": "users => Invalid parameter value detected: Unexpected keys (phone1, department, institution) detected in parameter array."
}
What should I do to fix that?
Just as the error suggests, that web service does not support the fields you are giving it. You can refer to the function itself to find out what fields are supported and what data they must contain.
core_user_get_users
I am not aware of a workaround for your problem using existing web services. However, you can create your own which includes those additional fields.
Note that this sounds to me like this is a desirable feature and should be raised on the issue tracker.
I want to get the mail subject and body of only unread mails of my inbox.
I want to read one unread mail at a time and mark it as read afterwards.
I need the subject, from address and mail body.
The below code shows gives me the mail IDs of all unread mails.
require_once ('../mail3/php-ews-master/ExchangeWebServices.php');
require_once ('../mail3/php-ews-master/EWS_Exception.php');
require_once ('../mail3/php-ews-master/EWSType.php');
require_once ('../mail3/php-ews-master/NTLMSoapClient.php');
function __autoload($class_name)
{
// Start from the base path and determine the location from the class name,
$base_path = '../mail3/php-ews-master';
$include_file = $base_path . '/' . str_replace('_', '/', $class_name) . '.php';
return (file_exists($include_file) ? require_once $include_file : false);
}
$ews = new ExchangeWebServices("servername", "username", "password",ExchangeWebServices::VERSION_2010);
$request = new EWSType_FindItemType();
$itemProperties = new EWSType_ItemResponseShapeType();
$itemProperties->BaseShape = EWSType_DefaultShapeNamesType::ID_ONLY;
$itemProperties->BodyType = EWSType_BodyTypeResponseType::BEST;
$request->ItemShape = $itemProperties;
$fieldType = new EWSType_PathToUnindexedFieldType();
$fieldType->FieldURI = 'message:IsRead';
$constant = new EWSType_FieldURIOrConstantType();
$constant->Constant = new EWSType_ConstantValueType();
$constant->Constant->Value = "0";
$IsEqTo = new EWSType_IsEqualToType();
$IsEqTo->FieldURIOrConstant = $constant;
$IsEqTo->Path = $fieldType;
$request->Restriction = new EWSType_RestrictionType();
$request->Restriction->IsEqualTo = new EWSType_IsEqualToType();
$request->Restriction->IsEqualTo->FieldURI = $fieldType;
$request->Restriction->IsEqualTo->FieldURIOrConstant = $constant;
$request->IndexedPageItemView = new EWSType_IndexedPageViewType();
$request->IndexedPageItemView->BasePoint = 'Beginning';
$request->IndexedPageItemView->Offset = 0;
$request->ParentFolderIds = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId = new EWSType_DistinguishedFolderIdType();
$request->ParentFolderIds->DistinguishedFolderId->Id = EWSType_DistinguishedFolderIdNameType::INBOX;
$request->Traversal = EWSType_ItemQueryTraversalType::SHALLOW;
$result = new EWSType_FindItemResponseMessageType();
$result = $ews->FindItem($request);
echo '<pre>';
print_r($result);
After getting it how can I mark the mail as read?
stdClass Object
(
[ResponseMessages] => stdClass Object
(
[FindItemResponseMessage] => stdClass Object
(
[ResponseCode] => NoError
[ResponseClass] => Success
[RootFolder] => stdClass Object
(
[Items] => stdClass Object
(
[Message] => Array
(
[0] => stdClass Object
(
[ItemId] => stdClass Object
(
[Id] => AAMkADM1NjQ4ZjU0LWI3OWYtNGZiMC1iYTgzLTU4N2E1MGMwYWNkMQBGAAAAAADANtAZyWYTTKe/pt+BZ+SXBwD+fIgCJQITS5O3LAEwY6+oAAAANbjBAAB51OTN2pqDQbTnOkGjBC0FAAGN2YkTAAA=
[ChangeKey] => CQAAABYAAAD+fIgCJQITS5O3LAEwY6+oAAC4WS4O
)
)
[1] => stdClass Object
(
[ItemId] => stdClass Object
(
[Id] => AAMkADM1NjQ4ZjU0LWI3OWYtNGZiMC1iYTgzLTU4N2E1MGMwYWNkMQBGAAAAAADANtAZyWYTTKe/pt+BZ+SXBwD+fIgCJQITS5O3LAEwY6+oAAAANbjBAAB51OTN2pqDQbTnOkGjBC0FAAGN2YkSAAA=
[ChangeKey] => CQAAABYAAAD+fIgCJQITS5O3LAEwY6+oAAC4WS35
)
)
)
)
[IndexedPagingOffset] => 2
[IncludesLastItemInRange] => 1
[TotalItemsInView] => 2
)
)
)
)
I see you're using the jamesiarmes/php-ews version of php-ews, so I'll try to answer for that. I might be a little bit off, since I don't use that version and will first encourage you to upgrade to a fork I maintain and update, because it's easier to use, you'll get more support, it's PSR-2 and 4 compatible and is still maintained. It's called garethp/php-ews. I'll give my answer for that first, as it's short and easy, then move to the code base you use
Solving with garethp/php-ews
Essentially there's three parts to it. Fetching, reading and marking as read. The first is to get only unread emails from the server, which is done as such
require_once "vendor/autoload.php";
use jamesiarmes\PEWS\API\Type;
use jamesiarmes\PEWS\Mail\MailAPI;
$api = MailAPI::withUsernameAndPassword('server', 'username', 'password');
$unreadMail = $api->getUnreadMailItems();
The second part of the solution is to read the item. EWS doesn't return the body of a mail item when you fetch a list of them. It considers the body to be a second class property, so you need to specifically ask for the information of that one mail item to get the body. So, in order to do that, we do the following
$item = $unreadMail[0];
$item = $api->getItem($item->getItemId());
$subject = $item->getSubject();
$sender = $item->getSender()->getMailbox()->getEmailAddress();
$body = (string) $item->getBody();
And the last part is to mark an item as read, which is done as such.
$api->markMailAsRead($item->getItemId());
The mail item should now show up as read. So, if we put them all together, it should come something like
require_once "vendor/autoload.php";
use jamesiarmes\PEWS\API\Type;
use jamesiarmes\PEWS\Mail\MailAPI;
$api = MailAPI::withUsernameAndPassword('server', 'username', 'password');
$unreadMail = $api->getUnreadMailItems();
foreach ($unreadMail as $item) {
$item = $api->getItem($item->getItemId());
$subject = $item->getSubject();
$sender = $item->getSender()->getMailbox()->getEmailAddress();
$body = (string) $item->getBody();
$api->markMailAsRead($item->getItemId());
}
Solving with jamesiarmes/php-ews
This is split up in to three steps (see above): Fetching, reading and marking as read. You know how to fetch, obviously. So we'll skip to the other two parts in one.
$result = $ews->FindItem($request);
foreach ($result->ResponseMessages->FindItemResponseMessage->RootFolder->Items->Message as $item) {
$request = new EWSType_GetItemType();
$request->ItemShape = new EWSType_ItemResponseShapeType();
$request->ItemShape->BaseShape = EWSType_DefaultShapeNamesType::ALL_PROPERTIES;
$request->ItemIds = new EWSType_NonEmptyArrayOfBaseItemIdsType();
$request->ItemIds->ItemId = new EWSType_ItemIdType();
$request->ItemIds->ItemId->Id = $item->ItemId->Id;
$response = $ews->GetItem($request);
//You may have to do a var_dump on the $response here. I'm only guessing that this is how you locate the message item, since I don't use this code base any more.
$item = $response->ResponseMessages->GetItemResponseMessage->Items->Message;
//You should do a var_dump on the $item to see how to get the body, subject and sender here. I'm not 100% sure how to do it on this one.
//Mark the item as read (hopefully)
$request = new EWSType_UpdateItemType();
$request->MessageDisposition = 'SaveOnly';
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = [];
$change = new EWSType_ItemChangeType();
$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $item->ItemId->Id;
$change->ItemId->ChangeKey = $item->ItemId->ChangeKey;
$change->Updates = new EWSType_NonEmptyArrayOfItemChangeDescriptionsType();
$change->Updates->SetItemField = array(); // Array of fields to be update
// Update Firstname (simple property)
$field = new EWSType_SetItemFieldType();
$field->FieldURI->FieldURI = 'message:IsRead';
$field->Message = new EWSType_MessageItemType();
$field->Message->IsRead = true;
$change->Updates->SetItemField[] = $field;
// Set all changes
$request->ItemChanges[] = $change;
// Send request
$response = $ews->UpdateItem($request);
echo '<pre>'.print_r($response, true).'</pre>';
}
Without actually testing it, that should be roughly how you would do it. You may have to play around with that to make it work. You can see why I suggest using my fork over this.
I would like to send emails only to users that have completed a specific course and add a pdf file (a certificate for completing the course) as attachment to the email, and do so at a specific time using moodle cron.
I have looked at some plugins to find out how it's done, but I'm still not sure how exactly I should do this.
I need:
1. to know how I would add an attachment to an email (and which API to use),
2. how I would use cron to send the emails to the desired group at a certain time,
3. how to retrieve users that have completed the course so that I could send emails (with attachment) to them.
Thanks in advance.
(I'm using moodle version 3.0)
This is an overview.
First create a local plugin. For example /local/yourplugin
https://docs.moodle.org/dev/Local_plugins
Then set up a message provider
https://docs.moodle.org/dev/Message_API
defined('MOODLE_INTERNAL') || die();
in local/yourplugin/db/messages.php
$messageproviders = array (
'coursecompleted' => array (
),
Then add an event observer - you will want to respond to the course_completed event
https://docs.moodle.org/dev/Event_2
in /local/yourpluginname/db/events.php
have something like
$observers = array(
array(
'eventname' => '\core\event\course_completed',
'callback' => 'local_yourplugin_observer::course_completed',
),
);
Now add the message code
Add something like this to '/local/message/classes/observer.php'
defined('MOODLE_INTERNAL') || die();
class local_yourplugin_observer {
/**
* Triggered when 'course_completed' event is triggered.
*
* #param \core\event\course_completed $event
* #return bool
*/
public static function course_completed(\core\event\course_completed $event) {
// Your code here.
$message = new \core\message\message();
$message->component = 'local_yourplugin'; // Name of your local plugin.
$message->name = 'coursecompleted'; // Name of message provider.
$message->userfrom = $USER;
$message->userto = $user;
$message->subject = 'message subject 1';
$message->fullmessage = 'message body';
$message->fullmessageformat = FORMAT_MARKDOWN;
$message->fullmessagehtml = '<p>message body</p>';
$message->smallmessage = 'small message';
$message->notification = '0';
$message->contexturl = 'http://GalaxyFarFarAway.com';
$message->contexturlname = 'Context name';
$message->replyto = "random#example.com";
$content = array('*' => array('header' => ' test ', 'footer' => ' test ')); // Extra content for specific processor
$message->set_additional_content('email', $content);
// Create a file instance.
$usercontext = context_user::instance($user->id);
$file = new stdClass;
$file->contextid = $usercontext->id;
$file->component = 'user';
$file->filearea = 'private';
$file->itemid = 0;
$file->filepath = '/';
$file->filename = '1.txt';
$file->source = 'test';
$fs = get_file_storage();
$file = $fs->create_file_from_string($file, 'file1 content');
$message->attachment = $file;
$messageid = message_send($message);
}
}
pretty new with the aws sdk, looking to start. i've installed the sdk and everything but how do I start the ec2 instances using the php sdk? Some code samples would really be useful.
Here is a basic example of starting a machine from a defined AMI:
$image_id = 'ami-3d4ff254'; //Ubuntu 12.04
$min = 1; //the minimum number of instances to start
$max = 1; //the maximum number of instances to start
$options = array(
'SecurityGroupId' => 'default', //replace with your security group id
'InstanceType' => 't1.micro',
'KeyName' => 'keypair', //the name of your keypair for auth
'InstanceInitiatedShutdownBehavior' => 'terminate' //terminate on shutdown
);
require_once('AWSSDKforPHP/sdk.class.php');
$ec2 = new AmazonEC2();
$response = $ec2->run_instances($image_id, $min, $max, $options);
if(!$response->isOK()){
echo "Start failed\n";
}
This is assuming you have your AWS credentials setup properly ... Hopefully this gets you pointed in the right direction ...
Here is a more detailed script if you are interested:
// Sleep time to allow EC2 instance to start up
$sleeptime = 15;
$username = "ec2-user";
// For AWS PHP SDK
putenv('HOME=/home/ec2-user/');
require_once 'AWSSDKforPHP/sdk.class.php';
// Get data from HTTP POST
$ami = $_POST['amis'];
$instancetype = $_POST['instancetype'];
$keyname = $_POST['key'];
$securitygroup = $_POST['securitygroups'];
// Instantiate the AmazonEC2 class
$ec2 = new AmazonEC2();
// Boot an instance of the image
$response = $ec2->run_instances($ami, 1, 1, array(
'KeyName' => $keyname,
'InstanceType' => $instancetype,
'SecurityGroupId' => $securitygroup,
));
if (!($response->isOK())) {
echo "<p class='error'>ERROR! Could not create new instance!</p>";
return;
}
$instance = $response->body->instancesSet->item->instanceId;
$message = "<p>Your instance has been successfully created.</p>";
$message .= ("<p>Instance ID is: <b>$instance</b></p>");
// Give instance some time to start up
sleep ($sleeptime);
// Get the hostname from a call to the DescribeImages operation.
$response = $ec2->describe_instances(array(
'Filter' => array(
array('Name' => 'instance-id', 'Value' => "$instance"),
)
));
if (!($response->isOK())) {
echo "<p class='error'>ERROR! Could not retrieve hostname for instance!</p>";
return;
}
$hostname = $response->body->reservationSet->item->instancesSet->item->dnsName;
// Output the message
$message .= "<p>Your instance hostname is: <b>$hostname</b></p>";
$message .= "<p>You can connect to your instance using this command:<br>" .
"<b>ssh -i $keyname.pem $username#" . $hostname . "</b></p>";
echo $message;
Pretty much the same as #dleiftah's, except that it outputs the hostname of the new instance upon completion.