Files
Umbraco-CMS/umbraco/cms/businesslogic/web/StyleSheet.cs
slace a5ba5ef1db DO NOT DOWNLOAD. DOWNLOAD LATEST STABLE FROM RELEASE TAB
More tweaks around the package upgrader

[TFS Changeset #56559]
2009-07-16 00:12:33 +00:00

497 lines
18 KiB
C#

using System;
using System.Collections;
using System.IO;
using System.Data;
using System.Xml;
using umbraco.DataLayer;
using System.Linq;
using System.Text.RegularExpressions;
using umbraco.cms.businesslogic.cache;
namespace umbraco.cms.businesslogic.web
{
/// <summary>
/// Summary description for StyleSheet.
/// </summary>
public class StyleSheet : CMSNode
{
private string _filename = "";
private string _content = "";
private StylesheetProperty[] m_properties;
public static Guid ModuleObjectType = new Guid("9f68da4f-a3a8-44c2-8226-dcbd125e4840");
private static object stylesheetCacheSyncLock = new object();
private static readonly string UmbracoStylesheetCacheKey = "UmbracoStylesheet";
public string Filename
{
get { return _filename; }
set
{
//move old file
//File.Move(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + this.Text + ".css"), System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + value + ".css"));
_filename = value;
SqlHelper.ExecuteNonQuery("update cmsStylesheet set filename = '" + _filename + "' where nodeId = " + base.Id.ToString());
InvalidateCache();
}
}
public string Content
{
get { return _content; }
set
{
_content = value;
SqlHelper.ExecuteNonQuery("update cmsStylesheet set content = @content where nodeId = @id", SqlHelper.CreateParameter("@content", this.Content), SqlHelper.CreateParameter("@id", this.Id));
InvalidateCache();
}
}
public StylesheetProperty[] Properties
{
get
{
if (m_properties == null)
{
BusinessLogic.console.IconI[] tmp = this.ChildrenOfAllObjectTypes;
StylesheetProperty[] retVal = new StylesheetProperty[tmp.Length];
for (int i = 0; i < tmp.Length; i++)
retVal[i] = StylesheetProperty.GetStyleSheetProperty(this.ChildrenOfAllObjectTypes[i].Id);
m_properties = retVal;
}
return m_properties;
}
}
//static bool isInitialized = false;
public StyleSheet(Guid id)
: base(id)
{
setupStyleSheet(true, true);
}
public StyleSheet(int id)
: base(id)
{
setupStyleSheet(true, true);
}
public StyleSheet(int id, bool setupStyleProperties, bool loadContentFromFile)
: base(id)
{
setupStyleSheet(loadContentFromFile, setupStyleProperties);
}
/// <summary>
/// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
/// </summary>
public override void Save()
{
SaveEventArgs e = new SaveEventArgs();
FireBeforeSave(e);
if (!e.Cancel) {
base.Save();
FireAfterSave(e);
}
}
private void setupStyleSheet(bool loadFileData, bool updateStyleProperties)
{
// Get stylesheet data
IRecordsReader dr = SqlHelper.ExecuteReader("select filename, content from cmsStylesheet where nodeid = " + base.Id.ToString());
if (dr.Read())
{
if (!dr.IsNull("filename"))
_filename = dr.GetString("filename");
// Get Content from db or file
if (!loadFileData)
{
if (!dr.IsNull("content"))
_content = dr.GetString("content");
}
else
if (File.Exists(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + this.Text + ".css")))
{
StreamReader re = File.OpenText(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + this.Text + ".css"));
string input = null;
bool read = true;
_content = string.Empty;
// NH: Updates the reader to support properties
bool readingProperties = false;
string propertiesContent = String.Empty;
while ((input = re.ReadLine()) != null && read)
{
if (input.Contains("EDITOR PROPERTIES"))
{
readingProperties = true;
}
else if (readingProperties)
{
propertiesContent += input.Replace("\n", "") + "\n";
}
else
{
_content += input.Replace("\n", "") + "\n";
}
}
re.Close();
// update properties
if (updateStyleProperties)
{
if (propertiesContent != String.Empty)
{
parseProperties(propertiesContent);
}
}
}
}
dr.Close();
}
private void parseProperties(string propertiesContent)
{
MatchCollection m =
Regex.Matches(propertiesContent, "([^{]*){([^}]*)}", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
foreach (Match match in m)
{
GroupCollection groups = match.Groups;
string cssClass = groups[1].Value.Replace("\n", "").Replace("\r", "").Trim().Trim(Environment.NewLine.ToCharArray());
string cssCode = groups[2].Value.Trim(Environment.NewLine.ToCharArray());
foreach (StylesheetProperty sp in this.Properties)
if (sp.Alias == cssClass)
sp.value = cssCode;
}
}
public static StyleSheet MakeNew(BusinessLogic.User user, string Text, string FileName, string Content)
{
// Create the umbraco node
CMSNode newNode = CMSNode.MakeNew(-1, ModuleObjectType, user.Id, 1, Text, Guid.NewGuid());
// Create the stylesheet data
SqlHelper.ExecuteNonQuery("insert into cmsStylesheet (nodeId, filename, content) values ('" + newNode.Id.ToString() + "','" + FileName + "',@content)", SqlHelper.CreateParameter("@content", Content));
// save to file to avoid file coherency issues
StyleSheet newCss = new StyleSheet(newNode.Id, false, false);
NewEventArgs e = new NewEventArgs();
newCss.OnNew(e);
return newCss;
}
public static StyleSheet[] GetAll()
{
ArrayList dbStylesheets = new ArrayList();
Guid[] topNodeIds = CMSNode.TopMostNodeIds(ModuleObjectType);
//StyleSheet[] retval = new StyleSheet[topNodeIds.Length];
for (int i = 0; i < topNodeIds.Length; i++)
{
//retval[i] = new StyleSheet(topNodeIds[i]);
dbStylesheets.Add(new StyleSheet(topNodeIds[i]).Text.ToLower());
}
ArrayList fileStylesheets = new ArrayList();
DirectoryInfo fileListing = new DirectoryInfo(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/"));
foreach (FileInfo file in fileListing.GetFiles("*.css"))
{
if (!dbStylesheets.Contains(file.Name.Replace(file.Extension, "").ToLower()))
{
fileStylesheets.Add(file.Name.Replace(file.Extension, ""));
}
}
StyleSheet[] retval = new StyleSheet[dbStylesheets.Count + fileStylesheets.Count];
for (int i = 0; i < topNodeIds.Length; i++)
{
retval[i] = new StyleSheet(topNodeIds[i]);
}
for (int i = 0; i < fileStylesheets.Count; i++)
{
string content = string.Empty;
using (StreamReader re = File.OpenText(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + fileStylesheets[i].ToString() + ".css")))
{
content = re.ReadToEnd();
}
retval[dbStylesheets.Count + i] = StyleSheet.MakeNew(new umbraco.BusinessLogic.User(0), fileStylesheets[i].ToString(), fileStylesheets[i].ToString(), content);
}
Array.Sort(retval, 0, retval.Length, new StyleSheetComparer());
return retval;
}
public StylesheetProperty AddProperty(string Alias, BusinessLogic.User u)
{
return StylesheetProperty.MakeNew(Alias, this, u);
}
new public void delete()
{
DeleteEventArgs e = new DeleteEventArgs();
FireBeforeDelete(e);
if (!e.Cancel) {
File.Delete(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + this.Text + ".css"));
foreach (StylesheetProperty p in this.Properties)
p.delete();
SqlHelper.ExecuteNonQuery("delete from cmsStylesheet where nodeId = @nodeId", SqlHelper.CreateParameter("@nodeId", this.Id));
base.delete();
FireAfterDelete(e);
}
}
public void saveCssToFile()
{
StreamWriter SW;
SW = File.CreateText(System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "/../css/" + this.Text + ".css"));
string tmpCss;
//tmpCss = "/* GENERAL STYLES */\n";
tmpCss = this.Content + "\n\n";
tmpCss += "/* EDITOR PROPERTIES - PLEASE DON'T DELETE THIS LINE TO AVOID DUPLICATE PROPERTIES */\n";
foreach (StylesheetProperty p in this.Properties)
{
tmpCss += p.ToString() + "\n";
}
SW.Write(tmpCss);
SW.Close();
}
public XmlNode ToXml(XmlDocument xd)
{
XmlNode doc = xd.CreateElement("Stylesheet");
doc.AppendChild(xmlHelper.addTextNode(xd, "Name", this.Text));
doc.AppendChild(xmlHelper.addTextNode(xd, "FileName", this.Filename));
doc.AppendChild(xmlHelper.addCDataNode(xd, "Content", this.Content));
if (this.Properties.Length > 0)
{
XmlNode properties = xd.CreateElement("Properties");
foreach (StylesheetProperty sp in this.Properties)
{
XmlElement prop = xd.CreateElement("Property");
prop.AppendChild(xmlHelper.addTextNode(xd, "Name", sp.Text));
prop.AppendChild(xmlHelper.addTextNode(xd, "Alias", sp.Alias));
prop.AppendChild(xmlHelper.addTextNode(xd, "Value", sp.value));
properties.AppendChild(prop);
}
doc.AppendChild(properties);
}
return doc;
}
public static StyleSheet GetStyleSheet(int id, bool setupStyleProperties, bool loadContentFromFile)
{
return Cache.GetCacheItem<StyleSheet>(GetCacheKey(id), stylesheetCacheSyncLock,
TimeSpan.FromMinutes(30),
delegate
{
try
{
return new StyleSheet(id, setupStyleProperties, loadContentFromFile);
}
catch
{
return null;
}
});
}
private void InvalidateCache()
{
Cache.ClearCacheItem(GetCacheKey(this.Id));
}
private static string GetCacheKey(int id)
{
return UmbracoStylesheetCacheKey + id;
}
//EVENTS
/// <summary>
/// The save event handler
/// </summary>
public delegate void SaveEventHandler(StyleSheet sender, SaveEventArgs e);
/// <summary>
/// The new event handler
/// </summary>
public delegate void NewEventHandler(StyleSheet sender, NewEventArgs e);
/// <summary>
/// The delete event handler
/// </summary>
public delegate void DeleteEventHandler(StyleSheet sender, DeleteEventArgs e);
/// <summary>
/// Occurs when [before save].
/// </summary>
public static event SaveEventHandler BeforeSave;
/// <summary>
/// Raises the <see cref="E:BeforeSave"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void FireBeforeSave(SaveEventArgs e)
{
if (BeforeSave != null)
BeforeSave(this, e);
}
/// <summary>
/// Occurs when [after save].
/// </summary>
public static event SaveEventHandler AfterSave;
/// <summary>
/// Raises the <see cref="E:AfterSave"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void FireAfterSave(SaveEventArgs e)
{
if (AfterSave != null)
AfterSave(this, e);
}
/// <summary>
/// Occurs when [new].
/// </summary>
public static event NewEventHandler New;
/// <summary>
/// Raises the <see cref="E:New"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void OnNew(NewEventArgs e)
{
if (New != null)
New(this, e);
}
/// <summary>
/// Occurs when [before delete].
/// </summary>
public static event DeleteEventHandler BeforeDelete;
/// <summary>
/// Raises the <see cref="E:BeforeDelete"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void FireBeforeDelete(DeleteEventArgs e)
{
if (BeforeDelete != null)
BeforeDelete(this, e);
}
/// <summary>
/// Occurs when [after delete].
/// </summary>
public static event DeleteEventHandler AfterDelete;
/// <summary>
/// Raises the <see cref="E:AfterDelete"/> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected virtual void FireAfterDelete(DeleteEventArgs e)
{
if (AfterDelete != null)
AfterDelete(this, e);
}
public static StyleSheet GetByName(string name)
{
try
{
int id = SqlHelper.ExecuteScalar<int>("SELECT id FROM umbracoNode WHERE text = @text AND nodeObjectType = @objType ", SqlHelper.CreateParameter("@text", name), SqlHelper.CreateParameter("@objType", StyleSheet.ModuleObjectType));
return new StyleSheet(id);
}
catch
{
return null;
}
}
public static StyleSheet Import(XmlNode n, umbraco.BusinessLogic.User u)
{
string stylesheetName = xmlHelper.GetNodeValue(n.SelectSingleNode("Name"));
StyleSheet s = GetByName(stylesheetName);
if (s == null)
{
StyleSheet.MakeNew(
u,
stylesheetName,
xmlHelper.GetNodeValue(n.SelectSingleNode("FileName")),
xmlHelper.GetNodeValue(n.SelectSingleNode("Content")));
}
foreach (XmlNode prop in n.SelectNodes("Properties/Property"))
{
string alias = xmlHelper.GetNodeValue(prop.SelectSingleNode("Alias"));
var sp = s.Properties.SingleOrDefault(p => p != null && p.Alias == alias);
string name = xmlHelper.GetNodeValue(prop.SelectSingleNode("Name"));
if (sp == default(StylesheetProperty))
{
sp = StylesheetProperty.MakeNew(
name,
s,
u);
}
else
{
sp.Text = name;
}
sp.Alias = alias;
sp.value = xmlHelper.GetNodeValue(prop.SelectSingleNode("Value"));
}
s.saveCssToFile();
return s;
}
}
public class StyleSheetComparer : IComparer
{
public StyleSheetComparer()
{
//default constructor
}
public Int32 Compare(Object pFirstObject, Object pObjectToCompare)
{
if (pFirstObject is StyleSheet)
{
return String.Compare(((StyleSheet)pFirstObject).Text, ((StyleSheet)pObjectToCompare).Text);
}
else
{
return 0;
}
}
}
}