所以,我可以调用Ajax并检查数据库中是否存在相同的书名,但我不知道Sugar CRM中控制器如何工作,也不知道如何在Sugar CRM中调用Ajax。
请问有人可以给予指导吗?非常感谢您的帮助。
如果您真的想使用ajax来完成这个任务,那么我建议使用entryPoint的方式。这个自定义过程需要几个简单的步骤。首先,您需要编写一些Javascript代码来执行实际的ajax调用。该ajax调用将会发布到您编写的entryPoint。entryPoint将会为您运行查询并在编辑视图中向您返回响应。因此,让我们首先编写entryPoint。
首先,打开custom/include/MVC/Controller/entry_point_registry.php文件。如果文件夹结构和文件不存在,请创建它们。
将以下代码添加到entry_point_registry.php文件中:
$entry_point_registry['test'] = array('file' => 'custom/test.php', 'auth' => true);
以下是关于那行代码的一些简短解释:
现在让我们来看看将要放置在 custom/test.php 中的代码(或者在您的情况下是 unique_book_name.php):
/* disclaimer: we are not gonna get all crazy with using PDO and parameterized queries at this point,
but be aware that there is potential for sql injection here. The auth => true will help
mitigate that somewhat, but you're never supposed to trust any input, blah blah blah. */
global $db; // load the global sugarcrm database object for your query
$book_name = urldecode($_REQUEST['book_name']); // we are gonna start with $_REQUEST to make this easier to test, but consider changing to $_POST when confirmed working as expected
$book_id = urldecode($_REQUEST['book_id']); // need to make sure this still works as expected when editing an existing record
// the $db->quote is an alias for mysql_real_escape_string() It still does not protect you completely from sql injection, but is better than not using it...
$sql = "SELECT id FROM book_module_table_name WHERE deleted = 0 AND name = '".$db->quote($book_name)."' AND id <> '".$db->quote($book_id)."'";
$res = $db->query($sql);
if ($db->getRowCount($res) > 0) {
echo 'exists';
}
else {
echo 'unique';
}
关于使用直接数据库查询的注意事项:可以使用api方法来完成此操作(提示:$bean->retrieve_by_string_fields() - 如果您想走这条路,请查看本文:http://developer.sugarcrm.com/2012/03/23/howto-using-the-bean-instead-of-sql-all-the-time/)。但是,我发现api非常缓慢,而且ajax应该尽可能快。如果客户要求提供此功能,我会有99%的机会使用直接db查询。如果那天我感觉很高级,可能会使用PDO和参数化查询,但由您决定。还是不起作用?你注意到https中的“s”了吗?尝试使用http并购买一个$9的ssl证书,拜托了,伙计!
好了,接下来让我们稍微测试一下entryPoint。向书籍模块添加记录。让我们添加《艺术战争》这本书(不是《战争艺术》,虽然您也应该读一读那本书)。
现在在url中添加这个:index.php?entryPoint=test&book_name=Art%20of%20War
哦天啊,这个url编码太丑陋了!别担心。
希望你能看到一个丑陋的白屏,上面会显示文本“存在”。如果可以,请确保它也可以反向操作。在URL中的书名后面添加2,希望它现在会显示“唯一”。
快速提示:如果你使用Sugar,你可能也在使用mysql,在搜索字符串时不区分大小写。如果你真的需要大小写敏感性,请查看这篇SO文章:如何使MySQL中的SQL区分大小写字符串比较?
好了,现在我们的entryPoint正在工作,我们可以继续进行让所有东西都变得ajaxical的有趣部分。有几种方法可以实现这一点,但与其走基本路线,我要向你展示我发现的最可靠的路线。
你可能需要创建以下文件:custom/modules/CUSTOM_BOOK_MODULE/views/view.edit.php(我希望现在我无需指出更改该路径以使用你的模块名称...)
假设这个文件不存在,我们从头开始,它将需要看起来像这样:
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class CUSTOM_BOOK_MODULEViewEdit extends ViewEdit
{
public function display()
{
// make sure it works in the subpanel too
$this->useForSubpanel = true;
// make the name value available in the tpl file
$this->ss->assign('name_value', $this->bean->name);
// load the parsed contents of the tpl into this var
$name_input_code = $this->ss->fetch('custom/modules/CUSTOM_BOOK_MODULE/tpls/unique_book_checker.tpl.js');
// pass the parsed contents down into the editviewdefs
$this->ss->assign('custom_name_code', $name_input_code);
// definitely need to call the parent method
parent::display();
}
}
情况看起来不错。现在我们需要编写代码到这个文件中:custom/modules/CUSTOM_BOOK_MODULE/tpls/unique_book_checker.tpl.js
首先,有几个假设:
我们期望这是Sugar 6.5+版本,并且jquery已经可用。如果您使用的是早期版本,则需要手动包含jquery。
我们将在名称字段上放置事件监听器。如果您要检查的书名值实际上是不同的字段名称,则只需在下面的javascript中进行调整。
以下是custom/modules/CUSTOM_BOOK_MODULE/unique_book_checker.tpl.js的代码:
<input type="text" name="name" id="name" maxlength="255" value="{$name_value}" />
<span id="book_unique_result"></span>
{literal}
<script type="text/javascript">
$(document).ready(function() {
$('#name').blur(function(){
$('#book_unique_result').html('<strong> checking name...</strong>');
$.post('index.php?entryPoint=test', {book_name: $('#name').val(), book_id: $('[name="record"]').val()}, function(data){
if (data == 'exists') {
removeFromValidate('EditView', 'name');
addToValidate('EditView', 'name', 'float', true, 'Book Name Must be Unique.');
$('#book_unique_result').html('<strong style="color:red;"> ✗</strong>');
}
else if (data == 'unique') {
removeFromValidate('EditView', 'name');
addToValidate('EditView', 'name', '', true, 'Name Required');
$('#book_unique_result').html('<strong style="color:green;"> ✓</strong>');
}
else {
// uh oh! maybe you have php display errors on?
}
});
});
});
</script>
{/literal}
注意:当代码检测到名称已经存在时,我们会使用Sugar内置的验证功能来防止记录保存。基本上,我们是在说如果名称已经存在,那么名称的值必须是浮点数。我认为这种情况很不可能发生并且能够奏效。但是,如果你有一本名为3.14或类似的书籍,并尝试创建重复项,此代码将无法阻止保存,它只会告诉你找到了一个重复项。
好了!最后两个步骤非常简单。 首先,打开文件:custom/modules/CUSTOM_BOOK_MODULE/metadata/editviewdefs.php。 接下来,找到提供名称字段元数据的部分,并添加此customCode属性,以使其看起来像这样:
array (
'name' => 'name',
'customCode' => '{$custom_name_code}',
),
最后,您需要进行快速修复和重建元数据以使更改生效。前往管理>维护>快速修复和重建。
完成了!您现在可以开始使用了!