【问题标题】:Silverstripe - cms fields not saving to databaseSilverstripe - cms 字段未保存到数据库
【发布时间】:2016-10-04 05:06:24
【问题描述】:

由于将站点移动到新服务器,配置选项卡下的表单字段不再保存到数据库。运行与旧服务器相同的配置,SilverStripe 2.3.3 和 PHP 5.2.17。看不到任何日志或 php 错误被抛出。

其他字段保存正常,因此问题特定于这组字段。

我假设这是负责该功能的代码。任何人都可以看到这不起作用的任何明显原因吗??

<?php

class Product extends Page {

public static $db = array(
    'ProductIntro' => 'Text',
    'ProductPrice' => 'Text',  
    'SpecialOffer' => 'Boolean',
    'HidePrice' => 'Boolean',
    'OneMonthPrice' => 'Currency',
    'ThreeMonthPrice' => 'Currency',
    'FourMonthPrice' => 'Currency',
    'SixMonthPrice' => 'Currency',
    'OutrightPrice' => 'Currency',
    'DeliveryPrice' => 'Currency',
    'DefaultPrice' => 'Enum("OneMonthPrice,ThreeMonthPrice,FourMonthPrice,SixMonthPrice","OneMonthPrice")',
    'VideoEmbedCode' => 'HTMLText'
);

public static $has_one = array(
    'ProductImage' => 'EnhancedImage'
);

public static $has_many = array(
    'ProductGalleryImages' => 'ProductGalleryImage',
    'ProductDownloads' => 'ProductDownload'
);

public static $many_many = array(
    'RelatedProducts' => 'Product'                               
);

static $belongs_many_many = array(
    'IsRelatedProduct' => 'Product'
);


static $allowed_children = array( );


public function getNextSibling() {

    return DataObject::get("Product", "ParentID = $this->ParentID && Sort > $this->Sort && Status = 'Published'", "Sort ASC", null, 1);
}

public function getPreviousSibling() {
    return DataObject::get("Product", "ParentID = $this->ParentID && Sort < $this->Sort && Status = 'Published'", "Sort DESC", null, 1);
}


public function SiblingProducts() {
     if ($this->getField("ParentID")) {

        return DataObject::get("Product", "ParentID = " . $this->getField("ParentID").' AND `SiteTree_Live`.ID != '.$this->getField("ID"));
    } else return false;
}

public function SubCategory() {
    if ($this->getField("ParentID")) {
        return DataObject::get_one("ProductSubCategory", "`SiteTree_Live`.ID = " . $this->getField("ParentID"));
    } else return false;
}

public function HasSubCategory() {
    if ($this->SubCategory()) {
        return true;
    } else {
        return false;
    }
}

public function Category() {
    if ($this->HasSubCategory()) {
        $parent_id = $this->SubCategory()->getField("ParentID");
    } else {
        $parent_id = $this->getField("ParentID");
    }
    if ($parent_id) {
        return DataObject::get("ProductCategory", "`SiteTree_Live`.ID = " . $parent_id);
    } else return false;
}

public function IsFeaturedProduct() {
    $hp = DataObject::get_one("ProductHomepage");
    if ($hp) {
        if ($hp->FeaturedProduct()) {
            if ($hp->FeaturedProduct()->getField('ID') && $hp->FeaturedProduct()->getField('ID') == $this->getField('ID')) return true;
        }
    }
    return false;
}

public function IsCategorySpecial() {

    if( $this->parent()->CategoryFeaturedProductID == $this->ID ) {
        return true;
    }

    return false;
}


function onAfterWrite() {  
if (isset($_POST['AddedViaObjectManager']) && $_POST['SetPageToLive'] && $this->stagesDiffer('Stage','Live')) {
    $this->Status = 'Published';
    $this->Publish('Stage', 'Live');
}
parent::onAfterWrite();
}

function getCMSFields_forPopup() {
  $fields = new FieldSet();
  $fields->push( new TextField( 'Title', 'Product Title' ) );
  $fields->push( new TextField( 'ProductIntro', 'Product Intro' ) );
  $fields->push( new TextField( 'ProductPrice', 'Price ($)' ) );
  $fields->push( new CheckboxField( 'SpecialOffer', 'This Product is a Special Offer' ) );
  $record = DataObject::get('ProductSubCategory', "");
  if ($record) {
      $map = $record->toDropDownMap('ID', 'Title');
  } else {
      $map = array();
  }
  $fields->push( new DropdownField('ParentID','Sub Category',$map) );
  $fields->push( new SimpleHTMLEditorField( 'Content', 'Content' ));
  $fields->push( new DropdownField('SetPageToLive','After Update, Set Product Page To:',array('1'=>'Live','0'=>'Draft')) );
  $fields->push( new FileIFrameField('ProductImage') );
  $fields->push( new HiddenField('AddedViaObjectManager','AddedViaObjectManager',1) );
  return $fields;
}

function getCMSFields() {
  $fields = parent::getCMSFields();

  $product = new VerticalTabSet(
        new VerticalTab('Configuration',array(
            new LiteralField("ConfDescription","<br /><em>Product pages support a range of additional features such as pricing.</em><br /><br />"),
            new TextField('ProductIntro', 'Intro Text'),
            new TextField('ProductPrice', 'From Text (Formerly Price)'),
            new CheckboxField("HidePrice","Hide Price"),
            new CheckboxField("SpecialOffer","This Product is currently on special."),
            new LiteralField("ldiv","<br /><br /><h2>Pricing</h2>"),
            new CurrencyField("OneMonthPrice", "One Month Hire Price"),
            new CurrencyField("ThreeMonthPrice", "Three Month Hire Price"),
            new CurrencyField("FourMonthPrice", "Four Month Hire Price"),
            new CurrencyField("SixMonthPrice", "Six Month Hire Price"),
            new CurrencyField("OutrightPrice", "Outright Purchase Price"),
            new CurrencyField("DeliveryPrice", "Delivery Price"),
            new DropDownField("DefaultPrice", "Selected Pricing Option", array('OneMonthPrice'=>'1 Month','ThreeMonthPrice'=>'3 Month','FourMonthPrice'=>'4 Month','SixMonthPrice'=>'6 Month'))
        )),
        new VerticalTab('RelatedProducts',array(
            new LiteralField("RelatedDescription","<br /><em>Related products are displayed on a product page to direct users to other options.</em><br /><br />"),
            new ManyManyDataObjectManager(
                $this, // Controller
                'RelatedProducts', // Source name
                'Product', // Source class
                array(
                    'Title' => 'Title'
                ), // Headings
                'getCMSFields_forPopup' // Detail fields (function name or FieldSet object)
            )
        )),
        new VerticalTab('Images',array(
            new LiteralField("ImageryDescription","<br /><em>The Main Image is used as the default image for this product.</em><br /><br />"),
            new FileIFrameField('ProductImage', 'Main Image'),
            new LiteralField ("ProdImages",'<br /><h4 style="margin-bottom:0px;padding-bottom:0px;">Upload Product Images</h4><br /><em>Supports all image types, however web images are recommended.</em><br /><br />'),
            new ImageDataObjectManager(
                $this, // Controller
                'ProductGalleryImages', // Source name
                'ProductGalleryImage', // Source class
                'Image', // File name on DataObject
                array(
                    'Title' => 'Title'
                ), // Headings
                'getCMSFields_forPopup' // Detail fields (function name or FieldSet object)
            )
        )),
        new VerticalTab('Downloads',array(
            new LiteralField("ImageryDescription","<br /><em>Add files users can download.</em><br /><br />"),
            new FileDataObjectManager(
                $this, // Controller
                'ProductDownloads', // Source name
                'ProductDownload', // Source class
                'File', // File name on DataObject
                array(
                    'Title' => 'Title'
                ), // Headings
                'getCMSFields_forPopup' // Detail fields (function name or FieldSet object)
            )
        )),
        new VerticalTab('Video',array(
            new LiteralField("VideoDescription","<br /><em>Add the embed code here.</em><br /><br />"),
            new TextareaField('VideoEmbedCode', 'Video Embed Code', 4)
        ))
  );

  $product->setOpenTab('Configuration');

  //$fields->addFieldToTab("Root.Content.Product",$product);

  $fields->insertAfter(new Tab('Configuration',$product),'Main');



  //$fields->insertAfter(new Tab('Related Products',$product_rel),'Main');



  //$main = $fields->fieldByName('Main');

  //$main->title = 'Product Details';


  return $fields;
}

 function HirePrices() {
   $prices = new DataObjectSet();

   $keys = array(
     'OneMonthPrice' => 'One Month',
     'ThreeMonthPrice' => 'Three Month',
     'FourMonthPrice' => 'Four Month',
     'SixMonthPrice' => 'Six Month',
   );
   $f = true;
   foreach($keys as $price_item => $title) {
       if ($this->$price_item > 0) {
           $p = $this->$price_item;
           $prices->push(new ArrayData( array(
                'price' => $p,
                'nice_price' => '$'.number_format($p,2),
                'title' => $title,
                'First' => $f,
                'IsDefault' => ($this->DefaultPrice == $price_item) ? true : false
            )));
           $f = false;
       }
   }

   return ($prices) ? $prices : false;

}

}

class Product_Controller extends Page_Controller {

public function init() {
    parent::init();

}

function Category() {
    return $this->data()->Category();
}

function SiblingProducts() {
    return $this->data()->SiblingProducts();
}



}

?>

【问题讨论】:

  • 如果这是一个页面,我会假设有一个 getCMSFields 函数,这将是在这里提供任何帮助的关键。如果您正在使用其他编辑表单,您能否澄清一下 - 例如模型管理员。
  • 运行/dev/build?flush=all时会发生什么?
  • Silverstripe 3.x 至少需要 PHP 5.3 才能运行。 PHP 5.2 已经完全过时了,你应该将你的服务器更新到最新的 php 5.6,它的运行速度也比旧的 5.2 快得多
  • 感谢您的反馈。站点正在运行 Silverstripe 2,有人告诉我它需要 PHP 5.2,它已经过时了,但是更容易维护在以前的服务器上运行的当前配置。这只是在我开发新网站时暂时的。
  • 开发/重建没有任何影响。甚至尝试创建一个新数据库,但问题仍然没有改变

标签: php database silverstripe


【解决方案1】:

从 Silverstripe 3.1 开始,$db 和其他定义必须声明为 private static 变量,以便配置系统可以缓存(和覆盖)它们。

<?php

class Product extends Page {

private static $db = array(
...
);

还有一个module that upgrades your code for you,它完成了 90% 的工作来让旧的 2.4 代码在 3.x 上运行。

【讨论】:

    【解决方案2】:

    虽然鼓励人们升级是合理的建议,但 OP 似乎有他们目前不这样做的理由。

    如果服务器配置和 PHP 版本相同,可以 - 但是数据库呢?您没有提及您在旧主机上使用的 RDBMS 和版本,以及您在新主机上使用的版本。

    第一件事是第一 - 有没有真的没有记录服务器错误?在您的新设置中,您的 php.ini 文件是否与旧服务器中的文件匹配?这个问题只在开发或生产中吗?在您的开发环境中,我强烈建议您将error_reporting 设置为E_ALLdislay_errors 设置为on。检查 php.ini 记录错误的位置。这可以是服务器的 syslog、apache 日志或专用的 php_errors 日志文件。确保这些文件中的每一个都是可读写的,否则不会记录任何内容。

    查看您的数据模型,我可以看到一些对DataObject::get() 的调用,其中一些原始SQL 作为SQL WHERE 子句插入。这没关系,但有些似乎不一致地转义(至少它们与您转义其他此类条款的方式不同),例如getPreviousSibling()getNextSibling()。您的 RDBMS(MySQL、Postgres 等)是否可能是不同的版本,对如何构造和转义传入的查询有不同的期望?

    您是否检查过 RDBMS 的查询日志?它说什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多