Commit 3f33fcfe authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Move artefact attachment code out of blogpost class

parent fc978154
......@@ -37,7 +37,7 @@ $id = param_integer('blogpost', 0);
if ($id) {
$blogpost = new ArtefactTypeBlogPost($id);
$blogpost->check_permission();
if (!$filelist = $blogpost->get_attached_files()) {
if (!$filelist = $blogpost->get_attachments()) {
$filelist = array();
}
}
......
......@@ -19,41 +19,5 @@
<KEY NAME="blogpostfk" TYPE="foreign" FIELDS="blogpost" REFTABLE="artefact" REFFIELDS="id" />
</KEYS>
</TABLE>
<!-- This table relates artefacts of type 'blogpost' to artefacts of type
'file'. This is a many-many relation. -->
<TABLE NAME="artefact_blog_blogpost_file">
<FIELDS>
<FIELD NAME="blogpost" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="file" TYPE="int" LENGTH="10" NOTNULL="true" />
</FIELDS>
<KEYS>
<KEY NAME="blogpost_filepk" TYPE="primary" FIELDS="blogpost,file" />
<KEY NAME="blogpostfk" TYPE="foreign" FIELDS="blogpost" REFTABLE="artefact" REFFIELDS="id" />
<KEY NAME="filefk" TYPE="foreign" FIELDS="file" REFTABLE="artefact" REFFIELDS="id" />
</KEYS>
</TABLE>
<!-- This table keeps track of files that are to be associated with a blog
post, but for which the post has not yet been created, or the association
has not yet been confirmed. No file should ever be in both this table and
artefact_blog_blogpost_file.
This table only keeps track of files that are specifically uploaded for a
blog post, not ones that have been uploaded already some other way, that
the user wants to associate with a blog post. -->
<TABLE NAME="artefact_blog_blogpost_file_pending">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
<FIELD NAME="oldextension" TYPE="text" NOTNULL="false" />
<FIELD NAME="filetype" TYPE="text" NOTNULL="false" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
......@@ -440,7 +440,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
return;
}
delete_records('artefact_blog_blogpost_file', 'blogpost', $this->id);
$this->detach(); // Detach all file attachments
delete_records('artefact_blog_blogpost', 'blogpost', $this->id);
parent::delete();
......@@ -484,7 +484,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
}
$smarty->assign('artefactdescription', $postcontent);
$smarty->assign('artefact', $this);
$attachments = $this->get_attached_files();
$attachments = $this->get_attachments();
if ($attachments) {
$this->add_to_render_path($options);
require_once(get_config('docroot') . 'artefact/lib.php');
......@@ -508,49 +508,8 @@ class ArtefactTypeBlogPost extends ArtefactType {
}
/**
* Returns an array of IDs of artefacts attached to this blogpost
*/
public function attachment_id_list() {
if (!$list = get_column('artefact_blog_blogpost_file', 'file', 'blogpost', $this->get('id'))) {
$list = array();
}
return $list;
}
public function attach_file($artefactid) {
$data = new StdClass;
$data->blogpost = $this->get('id');
$data->file = $artefactid;
insert_record('artefact_blog_blogpost_file', $data);
$data = new StdClass;
$data->artefact = $artefactid;
$data->parent = $this->get('id');
$data->dirty = true;
insert_record('artefact_parent_cache', $data);
// Ensure the attachment is recorded as being related to the blog as well
$data = new StdClass;
$data->artefact = $artefactid;
$data->parent = $this->get('parent');
$data->dirty = 0;
$where = $data;
unset($where->dirty);
ensure_record_exists('artefact_parent_cache', $where, $data);
}
public function detach_file($artefactid) {
delete_records('artefact_blog_blogpost_file', 'blogpost', $this->get('id'), 'file', $artefactid);
delete_records('artefact_parent_cache', 'parent', $this->get('id'), 'artefact', $artefactid);
// Remove the record relating the attachment with the blog
delete_records('artefact_parent_cache', 'parent', $this->get('parent'), 'artefact', $artefactid);
}
protected function count_attachments() {
return count_records('artefact_blog_blogpost_file', 'blogpost', $this->get('id'));
public function can_have_attachments() {
return true;
}
......@@ -595,16 +554,10 @@ class ArtefactTypeBlogPost extends ArtefactType {
if (count($result) > 0) {
// Get the attached files.
$idlist = implode(', ', array_map(create_function('$a', 'return $a->id;'), $result));
$files = get_records_sql_array('
SELECT
bf.blogpost, bf.file, a.artefacttype, a.title, a.description
FROM {artefact_blog_blogpost_file} bf
INNER JOIN {artefact} a ON bf.file = a.id
WHERE bf.blogpost IN (' . $idlist . ')', '');
$files = ArtefactType::attachments_from_id_list(array_map(create_function('$a', 'return $a->id;'), $result));
if ($files) {
foreach ($files as $file) {
$result[$file->blogpost]->files[] = $file;
$result[$file->artefact]->files[] = $file;
}
}
......@@ -656,7 +609,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
return true;
}
// Where to store temporary blog post files under dataroot
/* // Where to store temporary blog post files under dataroot
static $blogattachmentroot = 'artefact/blog/uploads/';
......@@ -668,7 +621,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
/**
* Returns the size of a temporary attachment
*/
public static function temp_attachment_size($uploadnumber) {
/* public static function temp_attachment_size($uploadnumber) {
return filesize(self::get_temp_file_path($uploadnumber));
}
......@@ -677,7 +630,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
* This function saves an uploaded file to a temporary directory in dataroot
* and saves the mime type info in the db for downloadtemp.php to read from.
*/
public static function save_attachment_temporary($inputname) {
/* public static function save_attachment_temporary($inputname) {
require_once('uploadmanager.php');
$um = new upload_manager($inputname);
db_begin();
......@@ -708,11 +661,10 @@ class ArtefactTypeBlogPost extends ArtefactType {
return $result;
}
/**
* Save a temporary uploaded file to the myfiles area.
*/
public function save_attachment($uploaddata) {
/* public function save_attachment($uploaddata) {
// Create the blogfiles folder if it doesn't exist yet.
$blogfilesid = self::blogfiles_folder_id();
......@@ -741,10 +693,11 @@ class ArtefactTypeBlogPost extends ArtefactType {
return false;
}
$this->attach_file($fileid);
$this->attach($fileid);
delete_records('artefact_blog_blogpost_file_pending', 'id', $uploaddata->tempfilename);
return $fileid;
}
*/
public static function blogfiles_folder_id($create = true) {
global $USER;
......@@ -803,7 +756,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
*
* @return array
*/
public function get_attached_files() {
/* public function get_attached_files() {
$list = get_records_sql_array('SELECT a.id, a.artefacttype, a.title, a.description
FROM {artefact_blog_blogpost_file} f
INNER JOIN {artefact} a ON a.id = f.file
......@@ -818,6 +771,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
}
return $list;
}
*/
public static function get_links($id) {
$wwwroot = get_config('wwwroot');
......@@ -836,7 +790,7 @@ class ArtefactTypeBlogPost extends ArtefactType {
if (isset($artefactcopies[$oldid]->oldattachments)) {
foreach ($artefactcopies[$oldid]->oldattachments as $a) {
if (isset($artefactcopies[$a])) {
$this->attach_file($artefactcopies[$a]->newid);
$this->attach($artefactcopies[$a]->newid);
}
$regexp[] = '#<img([^>]+)src="' . get_config('wwwroot') . 'artefact/file/download.php\?file=' . $a . '"#';
$replacetext[] = '<img$1src="' . get_config('wwwroot') . 'artefact/file/download.php?file=' . $artefactcopies[$a]->newid . '"';
......
......@@ -89,7 +89,7 @@ $old = $postobj->attachment_id_list();
foreach ($old as $o) {
if (!in_array($o, $artefacts)) {
$postobj->detach_file($o);
$postobj->detach($o);
}
}
......@@ -99,7 +99,7 @@ foreach ($old as $o) {
foreach ($artefacts as $a) {
if (!in_array($a, $old)) {
$postobj->attach_file($a);
$postobj->attach($a);
}
}
......
......@@ -364,7 +364,7 @@ abstract class ArtefactTypeFileBase extends ArtefactType {
return;
}
try {
delete_records('artefact_blog_blogpost_file', 'file', $this->id);
delete_records('artefact_attachment', 'attachment', $this->id);
}
catch ( Exception $e ) {}
delete_records('artefact_file_files', 'artefact', $this->id);
......@@ -396,12 +396,12 @@ abstract class ArtefactTypeFileBase extends ArtefactType {
$select = '
SELECT
a.id, a.artefacttype, a.mtime, f.size, a.title, a.description,
COUNT(c.id) AS childcount, COUNT (b.blogpost) AS attachcount';
COUNT(c.id) AS childcount, COUNT (aa.artefact) AS attachcount';
$from = '
FROM {artefact} a
LEFT OUTER JOIN {artefact_file_files} f ON f.artefact = a.id
LEFT OUTER JOIN {artefact} c ON c.parent = a.id
LEFT OUTER JOIN {artefact_blog_blogpost_file} b ON b.file = a.id';
LEFT OUTER JOIN {artefact_attachment} aa ON aa.attachment = a.id';
$where = "
WHERE a.artefacttype IN ('" . join("','", array_diff(PluginArtefactFile::get_artefact_types(), array('profileicon'))) . "')";
$groupby = '
......
......@@ -776,9 +776,108 @@ abstract class ArtefactType {
}
}
public function can_have_attachments() {
return false;
}
public function count_attachments() {
return count_records('artefact_attachment', 'artefact', $this->get('id'));
}
public function attachment_id_list() {
// During view copying, attachment_id_list can get called on artefacts of any type; don't call
// get_column here unless it might actually return something.
if ($this->can_have_attachments()) {
if ($list = get_column('artefact_attachment', 'attachment', 'artefact', $this->get('id'))) {
return $list;
}
}
return array();
}
public function attachments_from_id_list($artefactids) {
if (empty($artefactids)) {
return array();
}
$attachments = get_records_sql_array('
SELECT
aa.artefact, aa.attachment, a.artefacttype, a.title, a.description
FROM {artefact_attachment} aa
INNER JOIN {artefact} a ON aa.attachment = a.id
WHERE aa.artefact IN (' . join(', ', $artefactids) . ')', '');
if (!$attachments) {
return array();
}
return $attachments;
}
public function get_attachments() {
$list = get_records_sql_assoc('SELECT a.id, a.artefacttype, a.title, a.description
FROM {artefact_attachment} aa
INNER JOIN {artefact} a ON a.id = aa.attachment
WHERE aa.artefact = ?
ORDER BY a.title', array($this->id));
// load tags
if ($list) {
$tags = get_records_select_array('artefact_tag', 'artefact IN (' . join(',', array_keys($list)) . ')');
if ($tags) {
foreach ($tags as $t) {
$list[$t->artefact]->tags[] = $t->tag;
}
foreach ($list as &$attachment) {
if (!empty($attachment->tags)) {
$attachment->tags = join(', ', $attachment->tags);
}
}
}
}
// return $list;
return array_values($list);
}
public function attach($attachmentid) {
$data = new StdClass;
$data->artefact = $this->get('id');
$data->attachment = $attachmentid;
insert_record('artefact_attachment', $data);
$data = new StdClass;
$data->artefact = $attachmentid;
$data->parent = $this->get('id');
$data->dirty = true;
insert_record('artefact_parent_cache', $data);
// Ensure the attachment is recorded as being related to the parent as well
if ($this->get('parent')) {
$data = new StdClass;
$data->artefact = $attachmentid;
$data->parent = $this->get('parent');
$data->dirty = 0;
$where = $data;
unset($where->dirty);
ensure_record_exists('artefact_parent_cache', $where, $data);
}
}
public function detach($attachmentid=null) {
if (is_null($attachmentid)) {
delete_records('artefact_attachment', 'artefact', $this->id);
return;
}
delete_records('artefact_attachment', 'artefact', $this->get('id'), 'attachment', $attachmentid);
delete_records('artefact_parent_cache', 'parent', $this->get('id'), 'artefact', $attachmentid);
if ($this->get('parent')) {
// Remove the record relating the attachment with the parent
delete_records('artefact_parent_cache', 'parent', $this->get('parent'), 'artefact', $attachmentid);
}
}
// Interface:
public static function attached_id_list($attachmentid) {
return get_column('artefact_attachment', 'artefact', 'attachment', $attachmentid);
}
}
/**
......@@ -880,10 +979,6 @@ function rebuild_artefact_parent_cache_complete() {
function artefact_get_parents_for_cache($artefactid, &$parentids=false) {
static $blogsinstalled;
if (!isset($blogsinstalled)) {
$blogsinstalled = get_field('artefact_installed', 'active', 'name', 'blog');
}
$current = $artefactid;
if (empty($parentids)) { // first call
$parentids = array();
......@@ -893,8 +988,8 @@ function artefact_get_parents_for_cache($artefactid, &$parentids=false) {
break;
}
// get any blog posts it may be attached to
if (($parent->artefacttype == 'file' || $parent->artefacttype == 'image') && $blogsinstalled
&& $associated = get_column('artefact_blog_blogpost_file', 'blogpost', 'file', $parent->id)) {
if (($parent->artefacttype == 'file' || $parent->artefacttype == 'image')
&& $associated = ArtefactType::attached_id_list($parent->id)) {
foreach ($associated as $a) {
$parentids[$a] = 1;
artefact_get_parents_for_cache($a, $parentids);
......
......@@ -344,6 +344,17 @@
<KEY NAME="groupfk" TYPE="foreign" FIELDS="group" REFTABLE="group" REFFIELDS="id" />
</KEYS>
</TABLE>
<TABLE NAME="artefact_attachment">
<FIELDS>
<FIELD NAME="artefact" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="attachment" TYPE="int" LENGTH="10" NOTNULL="true" />
</FIELDS>
<KEYS>
<KEY NAME="artefact_attachmentpk" TYPE="primary" FIELDS="artefact,attachment" />
<KEY NAME="artefactfk" TYPE="foreign" FIELDS="artefact" REFTABLE="artefact" REFFIELDS="id" />
<KEY NAME="attachmentfk" TYPE="foreign" FIELDS="attachment" REFTABLE="artefact" REFFIELDS="id" />
</KEYS>
</TABLE>
<TABLE NAME="artefact_tag">
<FIELDS>
<FIELD NAME="artefact" TYPE="int" LENGTH="10" NOTNULL="true" />
......
......@@ -898,6 +898,48 @@ function xmldb_core_upgrade($oldversion=0) {
insert_record('cron', $cron);
}
if ($oldversion < 2009031800) {
// Files can only attach blogpost artefacts, but we would like to be able to attach them
// to other stuff. Rename the existing attachment table artefact_blog_blogpost_file to
// artefact_file_attachment so we don't end up with many tables doing the same thing.
execute_sql("ALTER TABLE {artefact_blog_blogpost_file} RENAME TO {artefact_attachment}");
if (is_postgres()) {
// Ensure all of the indexes and constraints are renamed
execute_sql("
ALTER TABLE {artefact_attachment} RENAME {blogpost} TO {artefact};
ALTER TABLE {artefact_attachment} RENAME {file} TO {attachment};
ALTER INDEX {arteblogblogfile_blofil_pk} RENAME TO {arteatta_artatt_pk};
ALTER INDEX {arteblogblogfile_blo_ix} RENAME TO {arteatta_art_ix};
ALTER INDEX {arteblogblogfile_fil_ix} RENAME TO {arteatta_att_ix};
ALTER TABLE {artefact_attachment} DROP CONSTRAINT {arteblogblogfile_blo_fk};
ALTER TABLE {artefact_attachment} ADD CONSTRAINT {arteatta_art_fk} FOREIGN KEY (artefact) REFERENCES {artefact}(id);
ALTER TABLE {artefact_attachment} DROP CONSTRAINT {arteblogblogfile_fil_fk};
ALTER TABLE {artefact_attachment} ADD CONSTRAINT {arteatta_att_fk} FOREIGN KEY (attachment) REFERENCES {artefact}(id);
");
}
else if (is_mysql()) {
// NOT TESTED YET...
execute_sql("ALTER TABLE {artefact_attachment} DROP FOREIGN KEY arteblogblogfile_blo_fk");
execute_sql("ALTER TABLE {artefact_attachment} CHANGE blogpost artefact BIGINT(10) DEFAULT NULL");
execute_sql("ALTER TABLE {artefact_attachment} ADD FOREIGN KEY(artefact) REFERENCES {artefact}(id)");
execute_sql("ALTER TABLE {artefact_attachment} DROP FOREIGN KEY arteblogblogfile_fil_fk");
execute_sql("ALTER TABLE {artefact_attachment} CHANGE file attachment BIGINT(10) DEFAULT NULL");
execute_sql("ALTER TABLE {artefact_attachment} ADD FOREIGN KEY(attachment) REFERENCES {artefact}(id)");
}
// Drop the _pending table. From now on files uploaded as attachments will become artefacts
// straight away. Hopefully changes to the upload/file browser form will make it clear to
// the user that these attachments sit in his/her files area as soon as they are uploaded.
$table = new XMLDBTable('artefact_blog_blogpost_file_pending');
drop_table($table);
}
return $status;
}
......
......@@ -27,7 +27,7 @@
defined('INTERNAL') || die();
$config = new StdClass;
$config->version = 2009031300;
$config->version = 2009031800;
$config->release = '1.2.0dev';
$config->minupgradefrom = 2008040200;
$config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment