private function index_search($data, $type = 'add') { $conf = realpath(CUR_CONF_PATH . 'conf/search_vod.ini'); if ($conf) { try { include_once ROOT_PATH . 'lib/xunsearch/XS.php'; $xs = new XS($conf); // 建立 XS 对象,项目名称为:demo $index = $xs->index; // 获取 索引对象 } catch (XSException $e) { return false; } if ($type == 'del') { $index->{$type}($data); return; } if ($data) { if (!is_array($data)) { $sql = "SELECT * FROM " . DB_PREFIX . 'vodinfo WHERE id=' . $data; $data = $this->db->query_first($sql); } $data = array('id' => $data['id'], 'title' => $data['title'], 'subtitle' => $data['subtitle'], 'comment' => $data['comment'], 'channel_id' => $data['channel_id'], 'vod_sort_id' => $data['vod_sort_id'], 'status' => $data['status'], 'vod_leixing' => $data['vod_leixing'], 'is_allow' => $data['is_allow'], 'from_appid' => $data['from_appid'], 'from_appname' => $data['from_appname'], 'duration' => $data['duration'], 'trans_use_time' => $data['trans_use_time'], 'mark_collect_id' => $data['mark_collect_id'], 'create_time' => $data['create_time'], 'playcount' => $data['playcount'], 'click_count' => $data['click_count'], 'downcount' => $data['downcount'], 'keywords' => $data['keywords'], 'bitrate' => $data['bitrate'], 'author' => $data['author'], 'video_order_id' => $data['video_order_id']); // 创建文档对象 $doc = new XSDocument(); $doc->setFields($data); // 添加到索引数据库中 $index->{$type}($doc); } } }
/** * Execute the console command. * * @return mixed */ public function fire() { $articles = Article::all(); $xs = new \XS('inspirer'); $xsindex = $xs->index; $xsindex->clean(); foreach ($articles as $article) { $doc = new \XSDocument(); $this->output->writeln(sprintf("<comment>[Add]</comment> article [id:<info>%d</info>] - %s", $article->id, $article->title)); $doc->setFields(['id' => $article->id, 'title' => $article->title, 'name' => $article->name, 'description' => $article->description, 'keyword' => $article->keywords, 'content' => $article->content]); $xsindex->add($doc); } }
public function xs_index() { $data = $this->input['data']; $type = $this->input['type'] ? $this->input['type'] : 'add'; $conf = realpath(CUR_CONF_PATH . 'data/' . $this->filename . '.ini'); if ($conf) { try { include_once CUR_CONF_PATH . 'lib/xunsearch/XS.php'; $xs = new XS($conf); // 建立 XS 对象,项目名称为:demo $index = $xs->index; // 获取 索引对象 } catch (XSException $e) { $this->errorOutput('ERROR'); } if ($type == 'clean') { $index->clean(); $this->addItem('true'); $this->output(); } if (empty($data)) { $this->errorOutput('NO_DATA'); } switch ($type) { case 'add': $doc = new XSDocument(); $doc->setFields($data); $index->add($doc); break; case 'update': $doc = new XSDocument(); $doc->setFields($data); $index->update($doc); break; case 'del': $index->del($data); break; case 'rebuild': $doc = new XSDocument(); $doc->setFields($data); $index->beginRebuild(); $index->add($doc); $index->endRebuild(); break; } $this->addItem('true'); $this->output(); } else { $this->errorOutput('NO_***.INI'); } }
public function afterSave($insert, $changedAttributes) { parent::afterSave($insert, $changedAttributes); $xs_unicom = new \XS('unicom'); $xs_index = $xs_unicom->index; $xs_data = array('id' => $this->id, 'question' => $this->question, 'answer' => $this->answer, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at); $xs_doc = new \XSDocument(); $xs_doc->setFields($xs_data); if ($insert) { $xs_index->add($xs_doc); } else { $xs_index->update($xs_doc); } }
/** * 添加或更新items * * @param string $dbName 库名称 * @param array $datas 单行数据(一维数组) | 多行数据(多维数组) * @param bool $add 是否是添加,为提高效率,如果确定是新增,设置为true */ public static function addOrUpdateItems($dbName, $datas, $add = FALSE) { self::init(); if (!is_array($datas) || empty($datas)) { return; } $datas = is_array($datas[0]) ? $datas : array($datas); $index = self::_getIndex($dbName); $index->openBuffer(); foreach ($datas as $data) { $doc = new \XSDocument(); $doc->setFields($data); // 更新 $index->update($doc, $add); } $index->closeBuffer(); }
public function index() { require './Vendor/xunsearch/lib/XS.php'; $xs = new \XS('test'); // 建立 XS 对象,项目名称为:demo $index = $xs->index; // 获取 索引对象 $dbJob = M('job', 'dg_', 'REMOTE_TEST_DB_DSN'); $lists = $dbJob->order('create_time desc')->select(); // 创建文档对象 $doc = new \XSDocument(); foreach ($lists as $val) { $data = array('job_id' => $val['job_id'], 'title' => $val['title'], 'work_type' => $val['work_type'], 'sex' => $val['sex'], 'money_way' => $val['money_way'], 'pay_way_money' => $val['pay_way_money'], 'province' => $val['province'], 'city' => $val['city'], 'create_time' => $val['create_time'], 'desc' => $val['desc']); $doc->setFields($data); // 添加到索引数据库中 $index->add($doc); } }
public static function setUpBeforeClass() { $data = array(array('pid' => 3, 'subject' => '关于 xunsearch 的 DEMO 项目测试', 'message' => '项目测试是一个很有意思的行为!', 'chrono' => 214336158, 'other' => 'master'), array('pid' => 11, 'subject' => '测试第二篇', 'message' => '这里是第二篇文章的内容', 'chrono' => 1314336168, 'other' => 'slave'), array('pid' => 21, 'subject' => '项目测试第三篇', 'message' => '俗话说,无三不成礼,所以就有了第三篇', 'chrono' => 314336178, 'other' => 'master')); // create object self::$xs = new XS(end($GLOBALS['fixIniData'])); $index = self::$xs->index; // create testing data $doc = new XSDocument('utf-8'); foreach ($data as $tmp) { $doc->setFields(null); $doc->setFields($tmp); $index->add($doc); } $index->addSynonym('project', '项目'); $index->flushIndex(); // create another db $index->setDb('db2'); foreach ($data as $tmp) { $tmp['pid'] += 1000; $doc->setFields(null); $doc->setFields($tmp); $index->add($doc); } // create synonyms on db2 $synonyms = array('test' => '测试', 'hello world' => '有意思', '迅搜' => 'xunsearch'); $index->openBuffer(); foreach ($synonyms as $raw => $syn) { $index->addSynonym($raw, $syn); } $index->addSynonym('test', 'quiz'); $index->closeBuffer(); // flush index & logging $index->flushIndex(); sleep(2); $index->flushLogging(); sleep(2); }
// begin rebuild if ($rebuild !== null) { echo "开始重建索引 ...\n"; $index->beginRebuild(); } // import data from source $fid = $xs->getFieldId(); if (!empty($source)) { echo "初始化数据源 ... {$source} \n"; $total = $total_ok = $total_failed = 0; $src = XSDataSource::instance($source, strpos($source, ':') ? $sql : $file); $dcs = $src->getCharset(); if ($dcs === false) { $dcs = $charset === null ? 'UTF-8' : $charset; } $doc = new XSDocument($dcs); echo "开始批量导入数据 (" . (empty($file) ? "请直接输入数据" : $file) . ") ...\n"; XSUtil::flush(); $index->setTimeout(0); $index->openBuffer(); while ($data = $src->getData()) { if ($source == 'csv') { $data = csv_transform($data); if (is_null($data)) { continue; } } $pk = $data[$fid->name]; if ($filter !== null && ($data = $filter->process($data, $dcs)) === false) { $total++; echo "警告:过滤器忽略了第 {$total} 条数据, 主键为:" . $pk . "\n";
// import data from source $fid = $xs->getFieldId(); if (!empty($source)) { echo "初始化数据源 ... {$source} \n"; $total = $total_ok = $total_failed = 0; $src = XSDataSource::instance($source, strpos($source, ':') ? $sql : $file); $dcs = $src->getCharset(); if ($dcs === false) { $dcs = $charset === null ? 'UTF-8' : $charset; } echo "开始批量导入数据 (" . (empty($file) ? "请直接输入数据" : $file) . ") ...\n"; XSUtil::flush(); $index->setTimeout(0); $index->openBuffer(); while ($data = $src->getData()) { $doc = new XSDocument($dcs); if ($source == 'csv') { $data = csvTransform($data); if (is_null($data)) { continue; } } $pk = $data[$fid->name]; if ($filter !== null && ($data = $filter->process($data, $dcs)) === false) { $total++; echo "警告:过滤器忽略了第 {$total} 条数据, 主键为:" . $pk . "\n"; continue; } $doc->setFields($data); try { if ($filter !== null && method_exists($filter, 'processDoc')) {
/** * Update the specified resource in storage. * * @param int $id * * @return Response */ public function update($id, Request $request) { $check = Validator::make($request->all(), ['title' => ['required', 'min:1', 'max: 255'], 'category_id' => ['required', 'numeric'], 'sort' => ['numeric'], 'name' => ['alpha_dash'], 'tag' => ['array'], 'display' => ['boolean']]); if ($check->fails()) { return redirect()->back()->withErrors($check->errors())->withInput(); } $article = Article::findOrFail($id); $insert = $request->only('title', 'category_id', 'keywords', 'sort', 'name', 'display'); $insert = array_merge($insert, ArticleProcess::convertArticle($request->input('content'))); $insert['description'] = $request->has('description') ? $request->input('description') : strip_tags((new Parsedown())->text($insert['description'])); extract($insert); $article->title = $title; $article->category_id = $category_id; $article->keywords = $keywords; $article->content = $content; $article->description = $description; $article->sort = $sort; $article->display = $display; if (isset($name)) { $article->name = $name; } $article->modified_at = date("Y-m-d H:i:s", time()); $article->save(); $xs = new \XS('inspirer'); // 保存至全文搜索索引 $doc = new \XSDocument(); $doc->setFields(['id' => $article->id, 'title' => $article->title, 'name' => $article->name, 'description' => $article->description, 'keyword' => $article->keywords, 'content' => $article->content]); $xs->index->update($doc); $article->tags()->sync($request->input('tag', [])); return redirect()->back(); }
/** * 更新索引文档 * 该方法相当于先根据主键删除已存在的旧文档, 然后添加该文档 * 如果你能明确认定是新文档, 则建议使用 {@link add} * @param XSDocument $doc * @param bool $add 是否为新增文档, 已有数据中不存在同一主键的其它数据 * @return XSIndex 返回自身对象以支持串接操作 */ public function update(XSDocument $doc, $add = false) { // before submit if ($doc->beforeSubmit($this) === false) { return $this; } // check primary key of document $fid = $this->xs->getFieldId(); $key = $doc->f($fid); if ($key === null || $key === '') { throw new XSException('Missing value of primarky key (FIELD:' . $fid . ')'); } // request cmd $cmd = new XSCommand(CMD_INDEX_REQUEST, CMD_INDEX_REQUEST_ADD); if ($add !== true) { $cmd->arg1 = CMD_INDEX_REQUEST_UPDATE; $cmd->arg2 = $fid->vno; $cmd->buf = $key; } $cmds = array($cmd); // document cmds foreach ($this->xs->getAllFields() as $field) { // value if (($value = $doc->f($field)) !== null) { $varg = $field->isNumeric() ? CMD_VALUE_FLAG_NUMERIC : 0; $value = $field->val($value); if (!$field->hasCustomTokenizer()) { // internal tokenizer $wdf = $field->weight | ($field->withPos() ? CMD_INDEX_FLAG_WITHPOS : 0); if ($field->hasIndexMixed()) { $cmds[] = new XSCommand(CMD_DOC_INDEX, $wdf, XSFieldScheme::MIXED_VNO, $value); } if ($field->hasIndexSelf()) { $wdf |= $field->isNumeric() ? 0 : CMD_INDEX_FLAG_SAVEVALUE; $cmds[] = new XSCommand(CMD_DOC_INDEX, $wdf, $field->vno, $value); } // add value if (!$field->hasIndexSelf() || $field->isNumeric()) { $cmds[] = new XSCommand(CMD_DOC_VALUE, $varg, $field->vno, $value); } } else { // add index if ($field->hasIndex()) { $terms = $field->getCustomTokenizer()->getTokens($value, $doc); // self: [bool term, NOT weight, NOT stem, NOT pos] if ($field->hasIndexSelf()) { foreach ($terms as $term) { $term = strtolower($term); $cmds[] = new XSCommand(CMD_DOC_TERM, 1, $field->vno, $term); } } // mixed: [use default tokenizer] if ($field->hasIndexMixed()) { $mtext = implode(' ', $terms); $cmds[] = new XSCommand(CMD_DOC_INDEX, $field->weight, XSFieldScheme::MIXED_VNO, $mtext); } } // add value $cmds[] = new XSCommand(CMD_DOC_VALUE, $varg, $field->vno, $value); } } // process add terms if (($terms = $doc->getAddTerms($field)) !== null) { // ignore weight for bool index $wdf1 = $field->isBoolIndex() ? 0 : CMD_INDEX_FLAG_CHECKSTEM; foreach ($terms as $term => $wdf) { $term = strtolower($term); $wdf2 = $field->isBoolIndex() ? 1 : $wdf * $field->weight; while ($wdf2 > XSFieldMeta::MAX_WDF) { $cmds[] = new XSCommand(CMD_DOC_TERM, $wdf1 | XSFieldMeta::MAX_WDF, $field->vno, $term); $wdf2 -= XSFieldMeta::MAX_WDF; } $cmds[] = new XSCommand(CMD_DOC_TERM, $wdf1 | $wdf2, $field->vno, $term); } } // process add text if (($text = $doc->getAddIndex($field)) !== null) { if (!$field->hasCustomTokenizer()) { $wdf = $field->weight | ($field->withPos() ? CMD_INDEX_FLAG_WITHPOS : 0); $cmds[] = new XSCommand(CMD_DOC_INDEX, $wdf, $field->vno, $text); } else { // NOT pos $wdf = $field->isBoolIndex() ? 1 : $field->weight | CMD_INDEX_FLAG_CHECKSTEM; $terms = $field->getCustomTokenizer()->getTokens($text, $doc); foreach ($terms as $term) { $term = strtolower($term); $cmds[] = new XSCommand(CMD_DOC_TERM, $wdf, $field->vno, $term); } } } } // submit cmd $cmds[] = new XSCommand(CMD_INDEX_SUBMIT); // execute cmd if ($this->_bufSize > 0) { $this->appendBuffer(implode('', $cmds)); } else { for ($i = 0; $i < count($cmds) - 1; $i++) { $this->execCommand($cmds[$i]); } $this->execCommand($cmds[$i], CMD_OK_RQST_FINISHED); } // after submit $doc->afterSubmit($this); return $this; }
/** * 获取匹配的搜索结果文档 * 默认提取最匹配的前 self::PAGE_SIZE 个结果 * 如需分页请参见 {@link setLimit} 设置, 每次调用本函数后都会还原 setLimit 的设置 * @param string $query 搜索语句, 若传入 null 使用默认语句, 最大长度为 80 字节 * @return XSDocument[] 匹配的搜索结果文档列表 */ public function search($query = null) { if ($this->_curDb !== self::LOG_DB) { $this->_highlight = $query; } $query = $query === null ? '' : $this->preQueryString($query); $page = pack('II', $this->_offset, $this->_limit > 0 ? $this->_limit : self::PAGE_SIZE); // get result header $cmd = new XSCommand(CMD_SEARCH_GET_RESULT, 0, $this->_defaultOp, $query, $page); $res = $this->execCommand($cmd, CMD_OK_RESULT_BEGIN); $tmp = unpack('Icount', $res->buf); $this->_lastCount = $tmp['count']; // load vno map to name of fields $ret = $this->_facets = array(); $vnoes = $this->xs->getScheme()->getVnoMap(); // get result documents while (true) { $res = $this->getRespond(); if ($res->cmd == CMD_SEARCH_RESULT_FACETS) { $off = 0; while ($off + 6 < strlen($res->buf)) { $tmp = unpack('Cvno/Cvlen/Inum', substr($res->buf, $off, 6)); if (isset($vnoes[$tmp['vno']])) { $name = $vnoes[$tmp['vno']]; $value = substr($res->buf, $off + 6, $tmp['vlen']); if (!isset($this->_facets[$name])) { $this->_facets[$name] = array(); } $this->_facets[$name][$value] = $tmp['num']; } $off += $tmp['vlen'] + 6; } } else { if ($res->cmd == CMD_SEARCH_RESULT_DOC) { // got new doc $doc = new XSDocument($res->buf, $this->_charset); $ret[] = $doc; } else { if ($res->cmd == CMD_SEARCH_RESULT_FIELD) { // fields of doc if (isset($doc)) { $name = isset($vnoes[$res->arg]) ? $vnoes[$res->arg] : $res->arg; $doc->setField($name, $res->buf); } } else { if ($res->cmd == CMD_OK && $res->arg == CMD_OK_RESULT_END) { // got the end break; } else { $msg = 'Unexpected respond in search {CMD:' . $res->cmd . ', ARG:' . $res->arg . '}'; throw new XSException($msg); } } } } } if ($query === '') { $this->_count = $this->_lastCount; // trigger to logQuery $this->logQuery(); // trigger to initHighlight $this->initHighlight(); } $this->_limit = $this->_offset = 0; return $ret; }
<?php require dirname(__DIR__) . '/config.php'; require APPSPATH . '/classes/xunsearch/lib/XS.php'; $wikis = table('wiki_tree')->gets(array('project_id' => 1)); $table = table('wiki_content'); echo "count=" . count($wikis) . "\n"; $xs = new XS(WEBPATH . '/search.ini'); $index = $xs->index; $index->beginRebuild(); foreach ($wikis as $v) { $wiki = $table->get($v['id'])->get(); $data = array('pid' => $v['id'], 'subject' => $v['text'], 'message' => $wiki['content'], 'chrono' => time()); $doc = new XSDocument(); $doc->setFields($data); $ret = $index->add($doc); echo "index #{$v['id']} ok\n"; } $index->endRebuild();
public function update(XSDocument $doc, $add = false) { if ($doc->beforeSubmit($this) === false) { return $this; } $fid = $this->xs->getFieldId(); $key = $doc->f($fid); if ($key === null || $key === '') { throw new XSException('Missing value of primary key (FIELD:' . $fid . ')'); } $cmd = new XSCommand(XS_CMD_INDEX_REQUEST, XS_CMD_INDEX_REQUEST_ADD); if ($add !== true) { $cmd->arg1 = XS_CMD_INDEX_REQUEST_UPDATE; $cmd->arg2 = $fid->vno; $cmd->buf = $key; } $cmds = array($cmd); foreach ($this->xs->getAllFields() as $field) { if (($value = $doc->f($field)) !== null) { $varg = $field->isNumeric() ? XS_CMD_VALUE_FLAG_NUMERIC : 0; $value = $field->val($value); if (!$field->hasCustomTokenizer()) { $wdf = $field->weight | ($field->withPos() ? XS_CMD_INDEX_FLAG_WITHPOS : 0); if ($field->hasIndexMixed()) { $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $wdf, XSFieldScheme::MIXED_VNO, $value); } if ($field->hasIndexSelf()) { $wdf |= $field->isNumeric() ? 0 : XS_CMD_INDEX_FLAG_SAVEVALUE; $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $wdf, $field->vno, $value); } if (!$field->hasIndexSelf() || $field->isNumeric()) { $cmds[] = new XSCommand(XS_CMD_DOC_VALUE, $varg, $field->vno, $value); } } else { if ($field->hasIndex()) { $terms = $field->getCustomTokenizer()->getTokens($value, $doc); if ($field->hasIndexSelf()) { $wdf = $field->isBoolIndex() ? 1 : $field->weight | XS_CMD_INDEX_FLAG_CHECKSTEM; foreach ($terms as $term) { if (strlen($term) > 200) { continue; } $term = strtolower($term); $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf, $field->vno, $term); } } if ($field->hasIndexMixed()) { $mtext = implode(' ', $terms); $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $field->weight, XSFieldScheme::MIXED_VNO, $mtext); } } $cmds[] = new XSCommand(XS_CMD_DOC_VALUE, $varg, $field->vno, $value); } } if (($terms = $doc->getAddTerms($field)) !== null) { $wdf1 = $field->isBoolIndex() ? 0 : XS_CMD_INDEX_FLAG_CHECKSTEM; foreach ($terms as $term => $wdf) { $term = strtolower($term); if (strlen($term) > 200) { continue; } $wdf2 = $field->isBoolIndex() ? 1 : $wdf * $field->weight; while ($wdf2 > XSFieldMeta::MAX_WDF) { $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf1 | XSFieldMeta::MAX_WDF, $field->vno, $term); $wdf2 -= XSFieldMeta::MAX_WDF; } $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf1 | $wdf2, $field->vno, $term); } } if (($text = $doc->getAddIndex($field)) !== null) { if (!$field->hasCustomTokenizer()) { $wdf = $field->weight | ($field->withPos() ? XS_CMD_INDEX_FLAG_WITHPOS : 0); $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $wdf, $field->vno, $text); } else { $wdf = $field->isBoolIndex() ? 1 : $field->weight | XS_CMD_INDEX_FLAG_CHECKSTEM; $terms = $field->getCustomTokenizer()->getTokens($text, $doc); foreach ($terms as $term) { if (strlen($term) > 200) { continue; } $term = strtolower($term); $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf, $field->vno, $term); } } } } $cmds[] = new XSCommand(XS_CMD_INDEX_SUBMIT); if ($this->_bufSize > 0) { $this->appendBuffer(implode('', $cmds)); } else { for ($i = 0; $i < count($cmds) - 1; $i++) { $this->execCommand($cmds[$i]); } $this->execCommand($cmds[$i], XS_CMD_OK_RQST_FINISHED); } $doc->afterSubmit($this); return $this; }
function makeindex() { if ($this->base->setting['xunsearch_open']) { $this->index->clean(); $query = $this->db->query("SELECT * FROM " . DB_TABLEPRE . "question "); while ($question = $this->db->fetch_array($query)) { $data = array(); $data['id'] = $question['id']; $data['cid'] = $question['cid']; $data['cid1'] = $question['cid1']; $data['cid2'] = $question['cid2']; $data['cid3'] = $question['cid3']; $data['author'] = $question['author']; $data['authorid'] = $question['authorid']; $data['answers'] = $question['answers']; $data['status'] = $question['status']; $data['time'] = $question['time']; $data['title'] = $question['title']; $data['description'] = $question['description']; $doc = new XSDocument(); $doc->setFields($data); $this->index->add($doc); } } }
public function testAddIndex() { $xs = new XS(end($GLOBALS['fixIniData'])); $doc = new XSDocument('UTF-8'); $doc->pid = '20061016'; $doc->subject = 'Hello, mazeyuan!'; $doc->message = 'I love you forever!'; // bool field 'date' split by '/' $doc->addIndex('date', 'Y2006/M10/D16'); // non-bool field (with stem), 'subject' $doc->addIndex('message', '你真是个小坏蛋'); $doc->addIndex('subject', '标是附加文字'); $xs->index->clean(); $xs->index->add($doc); $xs->index->flushIndex(); // wait for flushing sleep(3); $xs->search->setCharset('UTF-8'); // test search result about indexed terms $this->assertEquals(1, $xs->search->count('date:Y2006/M10')); $this->assertEquals(1, $xs->search->count('date:D16')); $this->assertEquals(1, $xs->search->count('subject:附加文字')); $this->assertEquals(1, $xs->search->count('真是个小坏蛋')); $xs->index->clean(); sleep(1); }
public function update($runValidation = true, $attributeNames = null) { if ($runValidation && !$this->validate($attributes)) { return false; } if (!$this->beforeSave(true)) { return false; } $db = static::getDb(); $values = $this->getDirtyAttributes($attributes); $doc = new XSDocument(); $doc->setFields($values); $db = static::getDb(); $db->getIndex()->update($doc); $changedAttributes = array_fill_keys(array_keys($values), null); $this->setOldAttributes($values); $this->afterSave(true, $changedAttributes); return true; }
/** * Populates an active record object using a xunsearch result document * * @param ActiveRecord $record the record to be populated. * @param \XSDocument $doc */ public static function populateRecord($record, $doc) { parent::populateRecord($record, $doc->getFields()); $record->setInternalDoc($doc); }