Silverstripe page relation in different languages - php

I have created a Link DataObject to automatically let users create a reference to a different page in the Frontend. I use two languages in the frontend, German and English. In the popup I create a dropdown to select the pages
public function getCMSFields_forPopup()
{
return new FieldSet(
new TextField('Titel'),
new TextField('URL', 'Externer Link'),
new SimpleTreeDropdownField('PageLinkID', 'Interner Link', 'SiteTree')
);
}
But I only get the German pages in the dropdown. Tried to change the admin language to English but no change. The database seems to only return the German pages...
Any clue?

Edit: I did some more digging and found out how to do this. You need to call "disable_locale_filter" before you get your SiteTree objects:
Translatable::disable_locale_filter();
Then call "enable_locale_filter" once you've retrieved them:
Translatable::enable_locale_filter();
These are other approaches which I'll leave here as I think they are still useful...
I believe you may have to do this using Translatable::get_by_locale() - I assume you only want people to be able to select a page to link to within their language??
Perhaps something like this?
public function getCMSFields_forPopup()
{
$member = Member::currentUser();
if($member && $member->Locale) {
$pagesByLocale = Translatable::get_by_locale('SiteTree', $member->Locale);
$pagesByLocale = $pagesByLocale->map('ID', 'Title', '(Select one)', true);
return new FieldSet(
new TextField('Title'),
new TextField('URL', 'Externer Link'),
new DropdownField('PageLinkID', 'Interner Link', $pagesByLocale);
);
} else {
// Handle non-member
}
}
Edit: see comments below but another option is to use the Translatable::get_current_locale() function to find all pages in the Site Tree for that locale... if the user is viewing an english page then the locale should be set to english etc...
public function getCMSFields_forPopup()
{
$pagesByLocale = Translatable::get_by_locale('SiteTree', Translatable::get_current_locale());
$pagesByLocale = $pagesByLocale->map('ID', 'Title', '(Select one)', true);
return new FieldSet(
new TextField('Title'),
new TextField('URL', 'Externer Link'),
new DropdownField('PageLinkID', 'Interner Link', $pagesByLocale);
);
}
You can also get the locale from the current page e.g.
$this->Locale; // From within the model
$this->dataRecord->Locale; // from within the controller
Director::get_current_page()->Locale; // If you're outside the context of the page altogether i.e. code inside your DataObject.

Related

How do I use the Cohort form in my plugin

How do I use the Form for creating a Cohort in Moodle in my own plugin?
I want to use the form, create the Cohort and return to a URL specified by with the Cohort id as a GET parameter ie http://myip/moodle/myplugin/myscrip.php?cohort_id=0
I've taken a look at the moodle files for the form but it's all chinese for me as i'm a complete novice as it comes to moodle development. What is the 'nice' way of using it?
The forms take a bit of getting used to, they are based on quickforms.
https://docs.moodle.org/dev/Form_API
https://docs.moodle.org/dev/lib/formslib.php_Usage
https://docs.moodle.org/dev/lib/formslib.php_Form_Definition
Usually there is a file named edit.php which uses the class in edit_form.php - but the file names can be anything.
You could take a copy of /cohort/edit.php and put it into your local plugin. If you are only creating cohorts and not updating them, then remove the update and delete code and keep the add cohort code:
$cohortid = cohort_add_cohort($data);
if ($usetags) {
if (isset($data->otags)) {
tag_set('cohort', $cohortid, tag_get_name($data->otags));
} else {
tag_set('cohort', $cohortid, array());
}
}
//update textarea
$data = file_postupdate_standard_editor($data, 'description', $editoroptions, $context, 'cohort', 'cohort', $cohortid);
$DB->set_field('cohort', 'description', $data->description, array('id' => $cohortid));
Then redirect to your link
$url = new moodle_url('/myplugin/myscrip.php', array('cohort_id' => $cohortid));
redirect($url);

Adding A New Page In CodeIgniter

I apologize in advance for my ignorance of CodeIgniter and the MVC system.
I'm helping a family member with their business website and up until now I've been able to complete most of the required changes just by using logic but now I've hit a dead end. I don't plan to continue supporting them as I'm obviously no CodeIgniter expert. But I'm hoping to leave the website at least functional, so that they can start using it.
I simply want to create a new "page" within the website but it seems impossible. If I can achieve this I think I can figure everything else out on my own.
For example I currently have a "page" for Cancelled Jobs. It the navigation HTML it is linked to like this:
http://localhost/admin/modules/cancelled_jobs
and has a corresponding file here: admin/application/controllers/cancelled_jobs.php
which contains this php code:
class Cancelled_jobs extends CIID_Controller {
public function __construct()
{
parent::__construct();
$this->set_table('job', 'Cancelled Job', 'Cancelled Jobs');
$this->allow_delete = false;
$this->allow_cancel = false;
$this->allow_edit = false;
$this->allow_reactivate = true;
$this->allow_add = false;
$this->overview
->add_item('Job No', 'active', 'job_id')
->add_item('Client', 'active|relationship', 'client.name')
->add_item('Name', 'active', 'name')
->add_item('Status', 'active|relationship', 'job_status.name')
->add_item('Assignee', 'active|relationship', 'team_member.name')
->add_item('Scheduled Date', 'active', 'scheduled_date')
->where("job.cancel_job = '1'")
->order_by('job.created_date DESC');
$this->init();
}
}
I would like to create a new "page" called Closed Jobs.
I've tried copying admin/application/controllers/cancelled_jobs.php and renaming it closed_jobs.php and changing the first line of code to read:
class Closed_jobs extends CIID_Controller {
I then add a link in the navigation HTML:
http://localhost/admin/modules/closed_jobs
However, when clicked, this only results in a "404 Page Not Found" error.
Can anyone point out what I'm missing in the process of creating a new page?
Generally, CodeIgniter URLstructure is:
sitename.com/controller_name/function_name/parameter_1/parameter_2/parameter_3/
You can add as many parameters as you want.
To access
modules/closed_jobs:
Add a new function in the controller modules
function closed_jobs() {
$this->load->view('closed_jobs');
}
And create a view closed_jobs.php
in application/views
Repeat the same for cancelled_jobs

Joomla render full article by id with "JModelLegacy getInstance article"

I'm stuck trying to get joomla full article to render in a tab. The tab is working. I just canĀ“t render the article content. This is where I am now.
This is helper.php
public static function getArticle($articleId)
{
JModelLegacy::addIncludePath(JPATH_SITE.'/components/com_content/models', 'ContentModel');
$model = JModelLegacy::getInstance('Article', 'ContentModel', array('ignore_request' => true));
$article = $model->getItem((int) $articleId);
$fullarticle = $item->fulltext;
$itemsHtml = '<div>'. $fullarticle .'</div>';
return $itemsHtml;
}
And this is in default.php
...code...
else if ($list_of_tabs['use'][$i][0] == 'article'){
echo '<div class="tab-pane '.$active.'" id="'.$i.$rid.'">'.
modJpTabsHelper::getArticle($list_of_tabs['article'][$i], $params) .
'</div>';
}
...code...
If you need more info. Don't hesitate to ask.
What are you trying to achieve: to write your own Joomla! extension which displays articles in a tab or you just need to display your J! articles in a tab?
If it's a latter, then there are already some nice and free (as in a "free bear") add-ons written just for that.
You are trying to use the model part of an MVC as a thing to render.
You should use the MVC system - using a controller to gathering the model and the view, and then you can render the model with the attached view, via the controller.
So you use something like (I've not tested this - you will need to correct it).
$filter=array('id' => $i->query['id']);
$options=array('filter_fields' => $filter,'ignore_request' => true);
$ctl = new ContentModelController();
$view = $ctl->getView( 'Article');
$model = $ctl->getModel( 'Article','',$options);
you may need to set params from application, eg..
$model->setState('params', JApplication::getInstance('site')->getParams());
then continue
$view->setModel( $model, true );
$result = $view->display();
Make sure that you have JLoader::import'ed any classes/classpaths - j. tends to fail silently if they aren't found, which can be difficult to trace.
Sorry, it's only a partial solution - but hopefully it may put you on the right track.
Here was the problem:
$fullarticle = $item->fulltext;
Article object from model was in variable $article not $item:
$article = $model->getItem((int) $articleId);
So getting property fulltext from article object should be:
$fullarticle = $article->fulltext;

Yiiframework First time login

I'm currently busy with a project that needs users to go to a specific page to create a profile when they log in for the first time (and haven't created one yet). Honestly, I don't know where to start. I would like to do it in a good way.
So in short:
User signs up -> logs in -> needs to fill in form before anything else is allowed -> continue to rest of application
Question: What is a neat way to do this? A solution that isn't going to give me problems in the future development of the application.
I suggest you to use filters. In every controller where the completed profile is neeeded add this code:
public function filters() {
return array(
'completedProfile + method1, method2, method3', // Replace your actions here
);
}
In your base controller (if you don't use base controller, in any controllers) you need to create the filter named completedProfile with the simular code:
public function filterCompletedProfile($filterChain) {
$criteria = new CDBCriteria(array(
'condition' => 'id = :id AND firstname IS NOT NULL AND lastname IS NOT NULL',
'params' => array(':id' => Yii::app()->user->getId())
));
$count = User::model()->count($criteria);
if ($count == 1) {
$filterChain->run();
} else {
$this->redirect(array('user/profile'));
}
}
Possibly add a field to the user profile database table which denotes if they have filled out their profile information. Something like profile_complete. Then you can do a test on pages to see if profile_complete is true and display the page if so, and display the profile page if not.

set upload folder in dataobject to the title of the related page - Silverstripe 3.1

hi i've got a gallery page. this gallery page has a gallery image object with an has_many relation.
private static $has_many = array(
'GalleryImages' => 'GalleryObject'
);
my gallery object has an image upload field. I want to set the upload folder to the title of the gallery page
i tried this with no result
$visual->setFolderName('Galerie/'.$this->Gallery()->Title);
and this (what i would prefer)
public function getGalleryTitle() {
$galleryTitle = $this->Gallery()->Title->First();
$uploadFolder = str_replace(' ', '-', $this->$galleryTitle);
return $uploadFolder;
}
$visual->setFolderName('Galerie/'.$this->$uploadFolder);
the second returns and error (undefined variable uploadFolder ?!) and my upload folder is now set to "Galerie/DataList"
can someone tell me how to convert the output of $uploadFolder so that i get back the title?
EDIT:
GalleryHolder: http://www.sspaste.com/paste/show/5267dea3579a6
GalleryPage: http://www.sspaste.com/paste/show/5267dee4c9752
GalleryObject: http://www.sspaste.com/paste/show/5267df0af1a65
you where almost there..
Here is your edited getGalleryTitle() function.
It is basically checking if the GalleryObject has a parent Gallery via $this->GalleryID. Since it is a has_one relation the column will be named GalleryID.
Then we get the Gallery object with $this->Gallery() and get it's title with $gallery->Title.
I've also replaced your str_replace with SilverStripe's URLSegmentFilter class. Which will removed spaces and other special characters non welcome in URL, a better solution.
public function getGalleryTitle()
{
if ( $this->GalleryID )
{
$gallery = $this->Gallery();
$filter = new URLSegmentFilter();
return $filter->filter( $gallery->Title );
}
else{
return 'default';
}
}
Then in the getCMSFields() function, when creating your UploadField we just call the getGalleryTitle() function that returns the string for the folder name.
$visual = new UploadField('Visual', _t('Dict.IMAGE', 'Image'));
$visual->setFolderName('Galerie/'.$this->getGalleryTitle());
A few notes..
$this references the current Object instance, so you can't use $this->$galleryTitle to access a variable you just created in your function, $galleryTitle by itself is enough.
You were calling $this->$uploadFolder in setFolderName, this doesn't work for the same reason, and also, using $uploadFolder by itself wouldn't work since this variable was created in the scope of another function. So we just call the function we defined on our Object with $this->getGalleryTitle() since it returns the value we want.
This should work fine, but keep in mind that if the Title of the Gallery changes at some point, the folder name will change too. So you might end up with images uploaded in many different folders for the same gallery... I personally wouldn't advise it, unless you implement some kind of "Title locking system" or some way to keep the "correct" or first "valid/acceptable" Gallery title in a separate object property that can't be edited and use this in the folder name.
I usually only use the ID in those case ($gallery->ID), as this will not change.
edit
Another version of getGalleryTitle() that should work even if the GalleryObject isn't saved yet.
public function getGalleryTitle()
{
$parentID = Session::get('CMSMain')['currentPage'];
if ( $parentID )
{
$gallery = Page::get()->byID( $parentID );
$filter = new URLSegmentFilter();
return $filter->filter( $gallery->Title );
}
else{
return 'default';
}
}
First, I check to see whether we're on the CMSSettingsPage or in a ModelAdmin page (Should you be using them). You want to get all the information about which class the controller is managing as it's data record. (If you have firebug, FB($this) in getCMSFields() on the related DataObject (DO) will show you the page managed under DataRecord)
Controller::curr()->currentPage() will get you the current page the DO is being managed on, and ->URLSegment will get the page url name, though you could use Title or MenuTitle also.
Here is an example which will set up a folder underneath assets/Headers to save images in. Running this on the HomePage (ie URL Segment 'home') will create and save objects into the folder /assets/Headers/home.
if (Controller::curr()->class == 'CMSSettingsController' || Controller::curr() instanceof Modeladmin) {
$uploadField->setFolderName('Headers');
}
else
{
$uploadField->setFolderName('Headers/' . Controller::curr()->currentPage()->URLSegment);
}

Categories