Below is my Customer dataobject
<?php
class Customer extends DataObject {
static $db = array(
'FirstName' => 'Varchar',
'Surname' => 'Varchar',
'Email' => 'Varchar',
'CustomerType' => "Enum('Private,Business','Private')"
);
static $has_one = array(
'Avatar' => 'Image',
);
static $has_many = array(
'HostingContracts' => 'HostingContract'
);
static $summary_fields = array(
'FirstName',
'Surname',
'CustomerType'
);
static $searchable_fields = array(
'FirstName',
'Surname',
'HostingContracts.ContractNumber'
);
}
?>
I need "Customer" to show as "Client" without changing the class name of the object.
Does anyone have an idea how to do this?
class Customer extends DataObject {
static $singular_name = 'Client';
static $plural_name = 'Clients';
}
Related
I have a plugin that is using OOP and it works perfectly on my localhost but not on my Bluehost server. It does not require any dependencies other than Composer autoload (i have uploaded composer generated vendor folder and json to remote plugin folder). I know the plugin is activating because it is generating empty database entries to my wp_options. However my add_menu_page function is not generating an options page in my Admin Dashboard.
I made sure that localhost and remote host are running same version of PHP (7.2+) and Wordpress (5.0.3)
I have already disabled all other plugins and tried uding in twentynineteen theme so I'm pretty confident it is not due to a conflict.
I have enabled debugging in wp_config and receive no errors.
I have no errors in my Bluehost error log
Below is a sample of my Dashboard.php....I'm only posting it because the lack of menu option is a symptom of my unknown error but i don't think its the cause
<?php
/**
* #package ICUPlugin
*/
namespace Inc\Pages;
use Inc\Api\SettingsApi;
use Inc\Base\BaseController;
use Inc\Api\Callbacks\AdminCallbacks;
use Inc\Api\Callbacks\ManagerCallbacks;
/**
*
*/
class Dashboard extends BaseController
{
public $settings;
public $callbacks;
public $callbacks_mgr;
public $pages = array();
//public $subpages = array();
public function register()
{
$this->settings = new SettingsApi();
$this->callbacks = new AdminCallbacks();
$this->callbacks_mgr = new ManagerCallbacks();
$this->setPages();
//$this->setSubpages();
$this->setSettings();
$this->setSections();
$this->setFields();
$this->settings->addPages( $this->pages )->withSubPage( 'Dashboard'
)->register();
}
public function setPages() {
$this->pages = array(
array(
'page_title' => 'ICU Plugin',
'menu_title' => 'ICU',
'capability' => 'manage_options',
'menu_slug' => 'icu_plugin',
'callback' => array( $this->callbacks, 'adminDashboard' ),
'icon_url' => 'dashicons-store',
'position' => 110
)
);
}
public function setSettings() {
$args = array(
array(
'option_group' => 'icu_plugin_settings',
'option_name' => 'icu_plugin',
'callback' => array( $this->callbacks_mgr, 'checkboxSanitize'
)
)
);
$this->settings->setSettings( $args );
}
public function setSections() {
$args = array(
array(
'id' => 'icu_admin_index',
'title' => 'Settings Manager',
'callback' => array( $this->callbacks_mgr,
'adminSectionManager' ),
'page' => 'icu_plugin'
)
);
$this->settings->setSections( $args );
}
public function setFields() {
$args = array();
foreach( $this->settingsManagers as $key => $value ) {
$args[] = array(
'id' => $key,
'title' => $value,
'callback' => array( $this->callbacks_mgr, 'checkboxField' ),
'page' => 'icu_plugin',
'section' => 'icu_admin_index',
'args' => array(
'option_name' => 'icu_plugin',
'label_for' => $key,
'class' => 'ui-toggle'
)
);
}
$this->settings->setFields( $args );
}
}
I am building an online shop. I am trying to implement a has_one : has_many relationship for DataObjects am managing using ModelAdmin with the use of radio buttons (OptionsetField in Silverstripe), but I have 2 problems.
The relations values are not getting saved into the database when I click save in the CMS.
The state does not persist so that when I log into the CMS next time I can see which radio button I selected last time.
Next is my code
---- Model Admin ----
<?php
class ProductAdmin extends ModelAdmin {
private static $menu_title = 'Store Manager';
private static $url_segment = 'StoreManager';
private static $managed_models = array (
'Product'=>array('title'=>'All Store Products'),
'ProductCategory'=>array('title'=>'Product Categories'),
'ProductSubcategory'=>array('title' => 'Product Sub Categories')
);
public $showImportForm = false;
}
---- Category ----
<?php
class ProductCategory extends DataObject {
private static $db = array (
'Title' => 'Varchar',
);
/**
* This relation links the Category to the Menu Items e.g. Category BoysClothing will be related to Boys * Menu Item.
*/
private static $has_one = array(
'Page' => 'Page'
);
private static $has_many = array (
'Subcategories' => 'ProductSubcategory'
);
public function getCMSFields(){
$fields = FieldList::create(TabSet::create('Root'));
$fields->addFieldsToTab('Root.Main', array(
TextField::create('Title', 'Name of Category'),
OptionsetField::create(
'Page', //name
'Page this category belongs to', //title
SiteTree::get()->filter(array('ShowInMenus' => '1'))->map('ID', 'Title'),
1
)
)//close array of fields
);//end adding fields to main tab
return $fields;
}
}
---- Product Sub Category ----
<?php
class ProductSubcategory extends DataObject {
private static $db = array (
'Title' => 'Varchar',
);
/**
* This relation links the Sub Category to the Category e.g. Category Khakis will be related to Boys
* Category
*
*/
private static $has_one = array(
'Category' => 'ProductCategory'
);//will lead to creation of column BoysPageID on the table BoysCategory
private static $has_many = array (
'Products' => 'Product'
);
public function getCMSFields(){
$fields = FieldList::create(TabSet::create('Root'));
$fields->addFieldsToTab('Root.Main', array(
TextField::create('Title', 'Name of Sub Category'),
DropdownField::create(
'Category',
'Category this subcategory belongs to',
ProductCategory::get()->map('ID', 'Title')
)
)//close array of fields
);//end adding fields to main tab
return $fields;
}
}//end class
---- Product ----
<?php
class Product extends DataObject{
private static $db = array (
'Title' => 'Varchar(255)',
'Price' => 'Varchar',
'Colors' => 'Varchar',
'Sizes' => 'Varchar',
'FeaturedOnHomepage' => 'Boolean'
);
private static $has_one = array (
'PrimaryPhoto' => 'Image',
'ProductSubcategory' => 'ProductSubcategory'
);
static $summary_fields = array (
'Title' => 'Name',
'Price' => 'Price',
'FeaturedOnHomepage.Nice' => 'Featured?',
'Thumbnail' => 'Picture'
);
public function getCMSFields(){
$fields = FieldList::create(TabSet::create('Root'));
$fields->addFieldsToTab('Root.Main', array(
TextField::create('Title', 'Name of product'),
TextField::create('Price', 'Price of product'),
TextField::create('Colors', 'Available Colors'), //Make this a checkbox set or multiselect drop down
TextField::create('Sizes', 'Available Sizes'), //Make this a checkbox set or multiselect drop down
CheckboxField::create('FeaturedOnHomepage', 'Feature On HomePage'),
CheckboxSetField::create(
'ProductSubcategory',
'Sub categories this product belongs to',
ProductSubcategory::get()->map('ID', 'Title')
),
$primary_photo = UploadField::create('PrimaryPhoto', 'Product Primary Photo')
)//close array of fields
);//end adding fields to main tab
//Add other photos related to this image in a deifferent tab
$other_product_photos = UploadField::create('ProductImages', 'Product Photo');
$fields->addFieldsToTab('Root.Other Photos', $other_product_photos);
//limit image extensions
$primary_photo->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
$other_product_photos->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
//set Folders
$primary_photo->setFolderName('ProductPhotos');
$other_product_photos->setFolderName('ProductPhotos');
//return
return $fields;
}
public function Link(){
$sview_link = "prods/sview/";
return $sview_link.$this->ID;
}
public function getThumbnail(){
if($this->PrimaryPhoto()->ID){
return $this->PrimaryPhoto()->setWidth(80);
}else{
return 'No Image';
}
}
}//close class Product
As Page is a has_one relation you need to add the suffix ID to the formfield (yes, that's annoying for beginners).
So
OptionsetField::create(
'PageID', //name
'Page this category belongs to', //title
SiteTree::get()->filter(array('ShowInMenus' => '1'))->map('ID', 'Title'),
1
)
should work. The same for the Category has_one in SubCategory.
You already stated in your code
//will lead to creation of column BoysPageID on the table BoysCategory
that's cause the has_one relation Foo is saved in DB as FooID, so we need to add the ID manually to the formfield.
I was wondering if it's possible to send batched requests to maps.googleapis.com. As far as I can tell, it isn't.
I was using the Google API Client Library with supports batching, but it's only for www.googleapis.com. I went ahead and hacked it so that I could call the Places API, and it worked fine for normal calls, but when I actually tried to batch them, I got a 404 error:
"The requested URL /batch was not found on this server. That’s all we know."
So it appears that maps.googleapis.com does not support batching, but I wanted to be sure this is true. If anyone knows otherwise, please tell me how. Thanks!
inside google-api-php-client/src/Google/Config.php:
- 'base_path' => 'https://www.googleapis.com',
+ 'base_path' => 'https://maps.googleapis.com',
google-api-php-client/src/Google/Service/Maps.php:
(I added this file to make Places calls possible.)
<?php
class Google_Service_Maps extends Google_Service
{
const MAPS = "https://maps.googleapis.com/auth/maps";
public function __construct(Google_Client $client)
{
parent::__construct($client);
$this->servicePath = 'maps/api/';
$this->version = 'v3';
$this->serviceName = 'maps';
$this->places = new Google_Service_Maps_Places_Resource(
$this,
$this->serviceName,
'places',
array(
'methods' => array(
'autocomplete' => array(
'path' => 'place/autocomplete/json',
'httpMethod' => 'GET',
'parameters' => array(
'input' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'sensor' => array(
'location' => 'query',
'type' => 'boolean',
'required' => true,
),
'location' => array(
'location' => 'query',
'type' => 'string',
),
'radius' => array(
'location' => 'query',
'type' => 'integer',
),
),
),
)
)
);
}
}
class Google_Service_Maps_Places_Resource extends Google_Service_Resource
{
public function autocomplete($input, $lat, $lng, $radius, $optParams = array())
{
$params = array('input' => $input, 'location' => "$lat,$lng", 'radius' => $radius, 'sensor' => false);
$params = array_merge($params, $optParams);
return $this->call('autocomplete', array($params));
}
}
API batch calling code:
<?php
const API_KEY = 'MY_API_KEY';
set_include_path("google-api-php-client/src/" . PATH_SEPARATOR . get_include_path());
require_once 'Google/Client.php';
require_once 'Google/Service/Maps.php';
require_once 'Google/Http/Batch.php';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey(API_KEY);
$client->setUseBatch(true);
$batch = new Google_Http_Batch($client);
$service = new Google_Service_Maps($client);
$inputs = array(
'Dolore',
'MacAl',
'App Aca'
);
foreach($inputs as $input) {
$req = $service->places->autocomplete($input, 37.7833, -122.4167, 500);
$batch->add($req, $input);
}
$results = $batch->execute();
print_r($results);
print_r($req);
I have problem with a contact form in symfony2 here is the code what i've done and what error do i get
<?php
// src/Aleksandar/IntelMarketingBundle/Resources/views/ContactType.php
namespace Aleksandar\IntelMarketingBundle\Resources\views;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Collection;
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text', array(
'attr' => array(
'placeholder' => 'What\'s your name?',
'pattern' => '.{2,}' //minlength
)
))
->add('email', 'email', array(
'attr' => array(
'placeholder' => 'So I can get back to you.'
)
))
->add('subject', 'text', array(
'attr' => array(
'placeholder' => 'The subject of your message.',
'pattern' => '.{3,}' //minlength
)
))
->add('message', 'textarea', array(
'attr' => array(
'cols' => 20,
'rows' => 2,
'placeholder' => 'And your message to me...'
)
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$collectionConstraint = new Collection(array(
'name' => array(
new NotBlank(array('message' => 'Name should not be blank.')),
new Length(array('min' => 2))
),
'email' => array(
new NotBlank(array('message' => 'Email should not be blank.')),
new Email(array('message' => 'Invalid email address.'))
),
'subject' => array(
new NotBlank(array('message' => 'Subject should not be blank.')),
new Length(array('min' => 3))
),
'message' => array(
new NotBlank(array('message' => 'Message should not be blank.')),
new Length(array('min' => 5))
)
));
$resolver->setDefaults(array(
'constraints' => $collectionConstraint
));
}
public function getName()
{
return 'contact';
}
}
?>
This is the code for the contact form which will be rendered in the view
no here is the code from my controller
<?php
namespace Aleksandar\IntelMarketingBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
/**
* #Route("/contact", _name="contact")
* #Template()
*/
public function contactAction()
{
$form = $this->createForm(new ContactType());
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$message = \Swift_Message::newInstance()
->setSubject($form->get('subject')->getData())
->setFrom($form->get('email')->getData())
->setTo('info#intelmarketing.es')
->setBody(
$this->renderView(
'AleksandarIntelMarketingBundle::contact.html.php',
array(
'ip' => $request->getClientIp(),
'name' => $form->get('name')->getData(),
'message' => $form->get('message')->getData()
)
)
);
$this->get('mailer')->send($message);
$request->getSession()->getFlashBag()->add('success', 'Your email has been sent! Thanks!');
return $this->redirect($this->generateUrl('contact'));
}
}
return array(
'form' => $form->createView()
);
}
}
and here is the rooting
aleksandar_intel_marketing_contactpage:
pattern: /contact
defaults: { _controller: AleksandarIntelMarketingBundle:Default:contact }
now when i try to open the page its says the fallowing:
"[Semantical Error] The annotation "#Route" in method
Aleksandar\IntelMarketingBundle\Controller\DefaultController::contactAction()
was never imported. Did you maybe forget to add a "use" statement for
this annotation? 500 Internal Server Error - AnnotationException "
If any one knows what might be the problem please let me know
As the error message states, you are missing a use statement on top of your controller file.
Simply add:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
on top of your class DefaultController.
You can then replace your routing with:
aleksandar_intel_marketing:
resource: "#AleksandarIntelMarketingBundle/Controller/DefaultController.php"
type: annotation
This way, you are using the #Route annotation instead of the default yml way to declare your routes.
http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html
I'm building a module (my_module) in Drupal 7.
It has some functionality and also will create new content type.
In my_module.install I implemented the hook_install (my_module_install).
Can I use more one implementation of hook_install to create new content type (my_cck_install) in this module?
If (yes), how should I do this?
Else: have I do this in another module? :-)
You can't use more than one implementation of hook_install in the same module; in PHP you can't have 2 function with the same name which rules this out.
You would just need to add your new content type in the same hook_install anyway (have a look at how the standard installation profile does it at /profiles/standard/standard.install). This is how I always add new content types from the install file (using the example of a testimonials module):
function testimonial_install() {
// Make sure a testimonial content type doesn't already exist
if (!in_array('testimonial', node_type_get_names())) {
$type = array(
'type' => 'testimonial',
'name' => st('Testimonial'),
'base' => 'node_content',
'custom' => 1,
'modified' => 1,
'locked' => 0,
'title_label' => 'Customer / Client Name'
);
$type = node_type_set_defaults($type);
node_type_save($type);
node_add_body_field($type);
}
}
The following code will create a content type called "Event" with a machine name of 'event' and a title field -
//CREATE NEW CONTENT TYPE
function orderform_node_info() {
return array(
'event' => array(
'name' => t('Event'),
'base' => 'event',
'description' => t('A event content type'),
'has_title' => TRUE
),
);
}
function event_form($node,$form_state) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('event Title'),
'#default_value' => !empty($node->title) ? $node->title : '',
'#required' => TRUE,
'#weight' => -5
);
return $form;
}
//END CONTENT TYPE
you should place it in your .module file... if you want do add additional fields to it, let me know and I'll patch you up with the code... good luck!
/**
* Implements hook_node_info()
*/
function mymodule_node_info() {
return array(
'news' => array(
'name' => t('News'),
'base' => 'news',
'description' => t('You can add News here'),
'has_title' => TRUE,
'title_label' => t('News title')
)
);
}
/**
* Implement hook_form()
*/
function mymodule_form($node, $form_state) {
return node_content_form($node, $form_state);
}
Add the implementation to mymodule.install is as follows:
/**
* Implements hook_install().
*/
function mymodule_install() {
node_types_rebuild();
$types = node_type_get_types();|
node_add_body_field($types['news']);
}
You can get a detailed description with code from here
/*
* Implementation in hook node info in .Module file
*/
function test_node_info() {
return array(
'product' => array(
'name' => t('Product'),
'base' => 'product',
'description' => t('Product Title'),
)
);
}
/**
* Implement hook_form()
*/
function product_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_install() in .install file.
*/
function test_install() {
node_types_rebuild();
$types = node_type_get_types();
node_add_body_field($types['product']);
//New way to implement to add fields in your content type
foreach (_test_installed_fields() as $field) {
field_create_field($field);
}
foreach (_test_installed_instances() as $fieldinstance) {
$fieldinstance['entity_type'] = 'node';
$fieldinstance['bundle'] = 'product';
field_create_instance($fieldinstance);
}
}
/*
* Define your fields
*/
function _test_installed_fields() {
$t = get_t();
return array(
'product_title123' => array(
'field_name' => 'product_title123',
'label' => $t('Product Title'),
'type' => 'text'
),
'description123' => array(
'field_name' => 'description123',
'label' => $t('Description'),
'type' => 'text'
),
);
}
/*
* Define your instance of fields
*/
function _test_installed_instances() {
$t = get_t();
return array(
'product_title123' => array(
'field_name' => 'product_title123',
'type' => 'text',
'label' => $t('Product Title'),
'widget' => array(
'type' => 'text_textfield'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Product Title'),
'type' => 'text'
)
)
),
'description123' => array(
'field_name' => 'description123',
'type' => 'text',
'label' => $t('Description'),
'widget' => array(
'type' => 'text_textarea_with_summary'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Description'),
'type' => 'text'
)
)
),
);
}
/**
* Implements hook_uninstall().
*/
function test_uninstall() {
$ournewtype = 'product';
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => $ournewtype));
$nodeids = array();
foreach ($result as $row) {
$nodeids[] = $row->nid;
}
node_delete_multiple($nodeids);
node_type_delete($ournewtype);
}
That's it.