Exists any way to list Materials in the Google Classroom Reports? I get the announcements and coursework, but materials not appears:
I'm using:
<?php
$client = $this->google->getClient();
$service = new Google_Service_Classroom($client);
$optParams = array(
'courseStates' => 'ACTIVE',
'pageSize' => 20,
'teacherId' => $teacher,
);
$results = $service->courses->listCourses($optParams);
foreach($results->getCourses() as $r)
{
$course = (string)$r->getId();
// coursework
$work = $service->courses_courseWork->listCoursesCourseWork($course, array());
// ...
// announcements
$announ = $service->courses_announcements->listCoursesAnnouncements($course, array('announcementStates' => 'PUBLISHED'));
// ...
}
// materials???
Edited 31/01/19:
I've tested the suggestion of #Mr.Rebot. The problem is Classroom API list only files o drive files attached in assigments... materials like this:
My problem is that I need to list the new Classroom option of materials:
So, when I query the ->getMaterials() of the coursework, I get an empty array()
You need to add the scope which is
Google_Service_Classroom::CLASSROOM_COURSEWORKMATERIALS
Google_Service_Classroom::CLASSROOM_COURSEWORKMATERIALS_READONLY
then you can retrieve the list by calling
$this->service->courses_courseWorkMaterials->listCoursesCourseWorkMaterials($course_id);
If you'll check the courses.courseWork overview, you'll see that materials[] is included there.
{
"courseId": string,
"id": string,
"title": string,
"description": string,
"materials": [
{
object(Material)
}
],
.......
Just get materials under courseWork response.
Related
In this example a have one blog that have multiple posts.
How can I add elements to a collection and keep everything a collection:
$post = collect(['title' => 'Hello', 'content' => 'world']);
$blog->posts->push($post);
And then access it with $blog->posts but instead I have to access it with $blog['posts'].
I have tried:
// First way
$blog = collect(['posts']);
$blog->posts->push($post);
// Second way
$blog = collect();
$blog->put('posts' [$post]);
// Third way
$blog = collect();
$blog->put('posts', collect([]));
$blog->posts->push($post);
I think you want to append new Article to the blog's articles.
In this case you have to do the following, in the below example:
$blog = Blog::find(1);
dump($blog->articles); // Two items retrieved
// New article
$newArticle = new Article([
'title' => 'Article Three',
'content' => 'Article Three',
]);
// Prepend to articles as a collection
$blog->articles->prepend($newArticle);
// Save it into DB [If you want]
// $blog->articles()->save($newArticle);
dd($blog->articles); // The collection updated with the new item.
Actually I'm on a laravel and reactJs project. I want to upload multiple pictures (album) with laravel and Cloudinary but I didn't find the right solution.
This my db migration file:
public function up()
{
Schema::create('unites', function (Blueprint $table) {
$table->increments('unit_id');
$table->unsignedInteger('building_id');
$table->foreign('building_id')->references('building_id')->on('buildings');
$table->unsignedInteger('floor_id');
$table->foreign('floor_id')->references('floor_id')->on('floors');
$table->string('unit_name',200);
$table->tinyinteger('unit_status');
$table->integer('unit_roomnumber');
$table->string('unit_type',5);
$table->string('unit_pictures');
$table->date('unit_added_date')->format("yyyy-MM-dd");
$table->timestamps();
});
}
An this My function in the controller :
else {
$unit = new Unite();
$unit ->unit_name = $request->input('unit_name');
$unit->building_id = $request->input('building_id');
$unit->floor_id = $request->input('building_id');
$unit->unit_type = $request->input('unit_type');
$unit->unit_status = $request->input('unit_status');
$unit->unit_roomnumber = $request->input('unit_roomnumber');
$unit->unit_added_date = $request->input('unit_added_date');
$images = $request->file('unit_pictures');
$uploaded = [];
foreach ($images as $image) {
error_log('for statement fires.');
Cloudinary::upload($image, null, [
'folder' => '/units',
// 'discard_original_filename' => true,
])->getSecurePath();
return array($uploaded);
}
$unit->unit_pictures=$request->file('unit_pictures');
$unit->save();
return response()->json([
'status' => 200,
]);
I would be very Thankful if anyone of you can help me
foreach ($request->file('images') as $imagefile) {
$uploadedFileUrl = Cloudinary::upload($imagefile->getRealPath())->getSecurePath();
}
The Cloudinary::upload() allows you to process a single asset at one time (see Upload API). For every upload, the response JSON will be returned containing all the information for the newly uploaded asset (see sample response JSON). If you wish to capture the results of every asset, you could collect them within the foreach, for example:
$unit->unit_pictures = $request->file('unit_pictures');
$allUploadApiReponse = array();
foreach ( $unit->unit_pictures=$request->file('unit_pictures') as $imagefile)
{
$uploadedFileUrl = Cloudinary::upload($imagefile->getRealPath(), [ 'folder' => 'Units' ] )->getSecurePath();
array_push($allUploadApiReponse, $uploadedFileUrl);
}
// To check content
print_r($allUploadApiReponse);
$unit->save();`
I'm having some issues with using Shopify's GraphQL API. I've already made a bunch of REST calls, but for this one I would need GraphQL.
I'm trying to add videos to certain products and this is what I have so far:
mutation productCreateMedia($productId: ID!, $media: [CreateMediaInput!]!) {
productCreateMedia(productId: $productId, media: $media) {
media {
alt
}
mediaUserErrors {
code
field
message
}
product {
id
}
}
}
and for variables, I have an array of:
$gid = "gid://shopify/Product/".row('shopifyID');
$videoLink = "https://www.youtube.com/watch?v=".row('youtubeID');
$media = array('originalSource'=>$videoLink,'mediaContentType'=>'EXTERNAL_VIDEO');
$variables = array ('productId'=>$gid,'media'=>$media);
I use the next function for the call:
function graph($query , $variables = []){
$domain = 'domain.myshopify.com';
$url = 'https://'.$domain.'/admin/api/2020-01/graphql.json';
$request = ['query' => $query];
if(count($variables) > 0) { $request['variables'] = $variables; }
$req = json_encode($request);
$parameters['body'] = $req;
$stack = HandlerStack::create();
$client = new \GuzzleHttp\Client([
'handler' => $stack,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'X-Shopify-Access-Token'=>'myAPIpass' // shopify app accessToken
],
]);
$response = $client->request('post',$url,$parameters);
return $body = json_decode($response->getBody(),true);
}
But what I'm getting back is:
Variable productId of type ID! was provided invalid value
I used php-shopify SDK for REST API, but couldn't figure out how it works for GraphQL, so went with the usual way of just calling the JSON endpoint.
Any help in what I'm doing wrong here?
So...to answer my own question...the shopify ID string has to be base 64 encoded.
I added just this line and it works now:
$gid = base64_encode($gid);
I am using xero api to integrate it with my web app to manage invoices, currently i want to update invoice through invoice id, i have an helper xero.php file to handle crud operations. I have a function get invoice by invoice id, i want to update the InvoiceNumber. What is the best way to update invoice?
update_invoice_function
public function update_invoice(){
$invoice_id = '******-***-****-****-************';
$updated_invoice = Xero::find_invoice_by_id($invoice_id);
$updated_invoice['response']->TotalDiscount = "1";
$updated_invoice['response']->Date = "2020-01-20";
$updated_invoice['response']->Status = "DRAFT";
$get_invoice_response = Xero::update_invoice_by_id($invoice_id,$updated_invoice['response']);
dd($get_invoice_response);
}
update_invoice_by_id function
public static function update_invoice_by_id($invoice_id,$updated_invoice){
self::instanciate();
try{
$update = self::$xero->loadByGUID('Accounting\\Invoice',$invoice_id);
dd($update);
$update->jsonSerialize($updated_invoice);
$invoice_response = self::$xero->save($update);
$response = [
'error' => false,
'status' => 200,
'message' => 'Invoice updated successfully',
'response' => $invoice_response->getElements()
];
}
catch (Exception $e){
$response = [
'error' => true,
'status' => $e->getCode(),
'message' => $e->getMessage()
];
}
return $response;
}
we have an example app that shows some sample calls to things like createInvoice.. However worth noting that there was recently a breaking change for the newer version of the API to support batch calls for invoice Create & Updates:
Older Way
$result = $apiInstance->updateInvoice($xeroTenantId, $guid, $invoice);
New Way
-> updateOrCreateInvoices is the newest way.. I recommend looking at your version of the package you are running as the function has changed.
https://github.com/XeroAPI/xero-php-oauth2-app/blob/4bf74e915df1b0fee66f954ffcbdc331e762a06a/example.php#L1222
However - in general, doing a POST on an existing invoice with the invoice ID and the New Number will enable you to update it.
{
"InvoiceID": "292532ba-xxxx-xxxx-xxxx-60e7c39c4360",
"InvoiceNumber": "INV-im-a-new-number"
}
Hope this un-blocks you!
I'm using Symfony 2.1 forms with PropelBundle and I'm trying to refactor a form that had a drop-down list of objects (to select from) to instead use a jquery autocomplete field (working with AJAX). For the dropdown list I was using the following code (which worked perfectly for the drop-down) in my form type:
$builder->add('books', 'collection', array(
'type' => 'model',
'options' => array(
'class' => 'MyVendor\MyBundle\Model\Book',
'property' => 'title',
),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'required' => false,
));
For the sake of giving a little context, let's say we are creating a new "Reader" object and that we would like to select the Reader's favorite books from a list of available "Book" objects. A collection type is used so that many "favorite books" can be selected in the new "Reader" form. Now, I would like to change the above to use autocomplete. For doing so, I tried to implement a Data Transformer to be able to get a Book object from a simple text field that could be used for the Autocomplete function to pass the Book ID as indicated in the answer to this Question. However, I was not able to figure out how to make the Data Transformer work with a collection type and Propel classes. I created a BookToIdTransformer class as indicated in the Symfony Cookbook and tried the following in the "ReaderType" file:
$transformer = new BookToIdTransformer();
$builder->add(
$builder->create('books', 'collection', array(
'type' => 'text',
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'required' => false,
))->addModelTransformer($transformer)
);
With the above, I get a "Call to undefined method: getId" exception (apparently the Transformer expects a PropelCollection of Books, not a single Book object..). Does anyone know how to go about it? or let me know if there are other ways to implement the autocomplete in Symfony using Propel and allowing for selecting multiple objects (e.g. a collection of books)?
The solution I ultimately went for is slightly different from my previous answer. I ended up using a "text" field type instead of a "collection" field type in my "ReaderType" form, since I ended up using the Loopj Tokeninput jQuery plugin which allows for selecting multiple objects (e.g. "Favorite Book") to associate to my main object (e.g. "Reader" object) in the form. Considering that, I created a "Data Transformer" for transforming the objects' ids passed (in a comma separated list in the text field) into a Propel Object Collection. The code is shared as follows, including a sample ajax object controller.
The key part of the "ReaderType" form looks as follows:
$transformer = new BooksToIdsTransformer();
$builder->add(
$builder->create('books', 'text', array(
'required' => false,
))->addModelTransformer($transformer)
);
The "Data Transformer" file looks like this:
// src/MyVendor/MyBundle/Form/DataTransformer/BooksToIdsTransformer.php
namespace MyVendor\MyBundle\Form\DataTransformer;
use \PropelObjectCollection;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use MyVendor\MyBundle\Model\BookQuery;
class BooksToIdsTransformer implements DataTransformerInterface
{
public function transform($books)
{
if (null === $books) {
return "";
}
if (!$books instanceof PropelObjectCollection) {
throw new UnexpectedTypeException($books, '\PropelObjectCollection');
}
$idsArray = array();
foreach ($books as $book) {
$idsArray[] = $book->getId();
}
$ids = implode(",", $idsArray);
return $ids;
}
public function reverseTransform($ids)
{
$books = new PropelObjectCollection();
if ('' === $ids || null === $ids) {
return $books;
}
if (!is_string($ids)) {
throw new UnexpectedTypeException($ids, 'string');
}
$idsArray = explode(",", $ids);
$idsArray = array_filter ($idsArray, 'is_numeric');
foreach ($idsArray as $id) {
$books->append(BookQuery::create()->findOneById($id));
}
return $books;
}
}
The ajax controller that returns a json collection of "books" to the Tokeninput autocomplete function is as follows:
namespace MyVendor\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use MyVendor\MyBundle\Model\BookQuery;
class ClassAjaxController extends Controller
{
public function bookAction(Request $request)
{
$value = $request->get('q');
$books = BookQuery::create()->findByName('%'.$value.'%');
$json = array();
foreach ($books as $book) {
$json[] = array(
'id' => $book->getId(),
'name' => $book->getName()
);
}
$response = new Response();
$response->setContent(json_encode($json));
return $response;
}
}
And finally, the router in the "routing.yml" file:
ajax_book:
pattern: /ajax_book
defaults: { _controller: MySiteBundle:ClassAjax:book }