I used drupal coder module to check my code and always get missing file doc as an error.
I used the following file doc comment but still showing error. Can you please guide me what am i doing wrong.
Edit:
<?php
/**
* #file
* Description
*/
/**
* Implements hook_menu().
*
* Description
*
* #return array An array of menu items
*/
function hook_menu() {
//My code
}
Typical first 15 lines of a file:
<?php
/**
* #file
* Description of what this module (or file) is doing.
*/
/**
* Implements hook_help().
*/
function yourmodule_help($path, $arg) {
// or any other hook...
}
Don't forget to also comment the first function of you file with /** or else coder will believe that your #file comment is your first function's comment.
Related
I have added some custom code in a block using PHP code format to show that block on a specific page. I have checked all the things working fine on Devel PHP page but contents are not showing on page. The code below fetches the field value of a destination node.
$refer = $_SERVER[HTTP_REFERER];
$parsed = parse_url($refer);
$alias = array_pop($parsed);
$dst = \Drupal::service('path.alias_manager')->getPathByAlias($alias , $langcode);
$nid = array_pop(explode('/', $dst));
$dest_node = node_load($nid);
$body = $dest_node->get('body')->getValue();
print $body; //have tried other printing methods also but invain
Hope this clarifies the question.
Thanks
Are you sure that it works in Devel? I've just tried to execute your code, and this line:
$body = $dest_node->get('body')->getValue();
returns Array.
Try to use this one instead:
$body = $dest_node->body->value;
First of all, your first block of code (getting current node) can be replaced with just one line:
$node = \Drupal::service('current_route_match')->getParameter('node');
And the whole block can be changed in the following way:
if ($node = \Drupal::service('current_route_match')->getParameter('node')) {
print $node->body->value;
}
P.S. And it's definitely a bad idea to use PHP text filter. You may easily write your own custom module providing required block. The simplest block plugin requires several lines of code:
/**
* #file
* Contains \Drupal\my_module\Plugin\Block\MyBlock.
*/
namespace Drupal\my_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides my super block.
*
* #Block(
* id = "my_module_block",
* admin_label = #Translation("My Block"),
* category = #Translation("My Module"),
* )
*/
class MyBlock extends BlockBase{
/**
* Builds and returns the renderable array for this block plugin.
*
* #return array
* A renderable array representing the content of the block.
*
* #see \Drupal\block\BlockViewBuilder
*/
public function build() {
if ($node = \Drupal::service('current_route_match')->getParameter('node')) {
return [ '#markup' => $node->body->value ];
}
}
}
This file MyBlock.php must be placed in /src/Plugin/Block/ directory inside your custom module named my_module.
In template i need to pass variable to controller when clicked link
{{ variable }}
click
.
How to do this?
/**
* #Route("/test", defaults={"variable" = 1}, name="test")
* #Method("GET")
* #Template()
*/
public function testAction($variable)
{
return array('variable'=>$variable);
}
You will say i need placeholder in #Route /test/{variable}, then how to first time visit url test?
edit: this is silly question. I had some cache problem while testing this issue. The answear is obvious.
You need to define your #Route annotation like you mention:
/**
* #Route("/test/{variable}", defaults={"variable" = 0}, name="test")
* #Method("GET")
* #Template()
*/
public function testAction($variable)
{
return array('variable'=>$variable);
}
Thanks to defaults option you can access your route with or without variable:
With:
click
This will generate url /test/2 and your $variable will equal 2
Without:
click
This will generate url /test and your $variable will equal 0 (a value set in defaults option)
I had to do something similar, and #Tomasz, your answer helped me a lot. I my case I needed two variables.
Using the above example as a reference:
* #Route("/test/{variable}/{var2}",
* defaults={"variable" = 0, "var2" = 0},
* name="test")
* #Method("GET")
* #Template()
*/
public function testAction($variable, $var2)
{
return array('variable'=>$variable, 'var2 => $var2);
}
Then in twig you can use:
click
which generates URL /test/2/3
In my case, I was using something more fancy, like an Entity:
<td><a href="{{ path('submitPetHasProgram',
{'prog':stu.getTcProgram.getProgramId,
'student':stu.getStuId}) }}">Select</a></td>
Hopefully this will help someone out in the future who is struggling for a solution to this type of problem.
I'm quite new with Doctrine, so I hope someone can help me or redirect me to the good documentation page.
I'm building an app with two entity (I reduce for explanations) :
- Tender
- File
For each tender, we can have one or more files. So I made the following objects.
Tender:
<?php
namespace TenderBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="tender")
*/
class Tender
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $tender_id;
/**
* #ORM\Column(type="array")
* #ORM\ManyToOne(targetEntity="File", inversedBy="tenders")
* #ORM\JoinColumn(name="tender_files", referencedColumnName="file_id")
*/
private $tender_files;
}
File:
<?php
namespace TenderBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* #ORM\Entity
* #ORM\Table(name="file")
*/
class File
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $file_id;
/**
* #ORM\OneToMany(targetEntity="Tender", mappedBy="tender_files", cascade={"persist", "remove"})
*/
private $file_tender;
}
First question: is it the right way to do this?
(of course, i've created the methods to get and set attributes, but they're basic).
When I persist each of my File object i'm trying to add then to my Tender instance. But to do this, I need to make $tender_files public and do this:
$tender->tender_files[]
This is not a viable solution for me because I need all my fields are private and I want to recover my object when I try to call this:
$this->getDoctrine()->getManager()->getRepository('TenderBundle:Tender')->find($id)->getTenderFiles()->getFileName();
So, I'm explaining and asking to find the right way to do what I want. I hope what i need is clear and i'm here to answers questions or show more code if needed.
Thanks!
Like Richard has mentioned, you're missing getters and setters which are declared to be public. They'll have access to your private variables. The quick way to do this with symfony:
php app/console doctrine:generate:entities
It'll generate something like this:
public function addTenderFile(\TenderBundle\Entity\File $file)
{
$this->tender_files[] = $file;
return $this;
}
/**
* Remove
*/
public function removeTenderFile(\TenderBundle\Entity\File $file)
{
$this->tender_files->removeElement($file);
}
/**
* Get
*/
public function getTenderFiles()
{
return $this->tender_files;
}
It's good practice if you're a beginner to see how your code lines up with the auto generator. Once you understand what's going on, just let the generator do the grunt work.
You should have a setter and getter in your File entity similar to this:
public function setTender(\Your\Namespace\Tender $tender)
{
$this->tender = $tender;
return $this;
}
public function setTender()
{
return $this->tender;
}
So when you instance (or create) File, you can go like so:
$file = new File(); // or file fetched from DB, etc.
// here set $file properties or whatever
$tender->setFile($file);
$entityManager->persist($tender);
$entityManager->flush();
Then your tender will be properly associated with your file.
Similarly from the File end, you should be able to do:
$file->addTender($tender);
$entityManager->persist($file);
$entityManager->flush();
And your tender will be added to your File->tenders collection.
For more information the documentation is very useful and has more or less everything you need to get started.
Also, save yourself manually creating getters and setters by using generate:doctrine:entity
This is incorrect:
/**
* #ORM\Column(type="array")
* #ORM\ManyToOne(targetEntity="File", inversedBy="tenders")
* #ORM\JoinColumn(name="tender_files", referencedColumnName="file_id")
*/
private $tender_files;
You can't persist an array to your database. A database row is one entity and it's corresponding attributes. If a tender can have many files, then this relationship should be:
* #ORM\OneToMany
Likewise for the File entity. If many files can have one Tender then it's relationship should be:
* #ORM\ManyToOne
For relationship mapping using Doctrine, it's helpful to read left-to-right with the entity YOU'RE CURRENTLY IN being on the left, and the entity you're setting as a variable being on the right.
If you're in Tender reading left-to-right Tender may have "OneToMany" files. And File(s) may have ManyToOne Tender. Doctrine Association Mapping
In my Symfony2 app I have a need to provide an option to upload a text file. I've already achieved this by using the FormBuilderInterface to create a field with the 'file' type. The file gets uploaded properly but all I really need is to fetch the text from the file and insert it into the proper db table column. Is there a way to fetch the text from an uploaded file on POST? Thanks.
There are at least two ways.
Using Form Events
Using lifecycle callbacks
In both cases the main point is to open uploaded and fill its content to the entity property (after form posted but before data persisted to db). So you need to have 2 entity properties for this: uploaded file handler (not mapped to the db) and file text itself (mapped to the db).
Here is an example with the lifecycle callbacks:
Entity:
/**
* #ORM\Entity()
* #ORM\HasLifecycleCallbacks
*/
class SomeEntity {
/**
* Virtual field used for handling the file
*
* #Assert\File()
*/
private $fileHandler;
/**
* #var string
*
* #ORM\Column(type="text")
*/
private $file;
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function saveFileContent()
{
$tmpName = md5(uniqid(mt_rand(), true)) . '.' . $this->fileHandler->guessExtension();
try
{
$this->fileHandler->move(
'../../../tmp/',
$tmpName
);
} catch (\Exception $e) {}
$this->setFile(file_get_contents('../../../tmp/' . $tmpName));
unlink('../../../tmp/' . $tmpName);
}
}
This also might be helpfull: How to handle File Uploads with Doctrine
I need to add functionality to attach a file to a comment. The upload of the image would automatically when the user drops the file into the form (in the same way that you attach a file with gmail). My question is how do I do to find the file that was previously sent to the server when the comment is submitted and to delete the comment if the document is never submitted.
Do any of you have already done something similar?
Here's the association I have between my classes Comment and Document.
class Comment extends BaseComment
{
/** ... */
/**
* #ORM\ManyToMany(targetEntity="Document", cascade={"persist","remove"})
* #ORM\JoinTable(name="fls_comment_and_documents",
* joinColumns={#ORM\JoinColumn(name="comment_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="document_id", referencedColumnName="id", unique=true)}
* )
*
* #var ArrayCollection $documents
*/
protected $documents;
/** ... */
}
Thanks in advance !