Renamed the "Modify By" field after using Elevated Mode - sharepoint

I'm currently facing to an issue using the Elevated Mode used in a Feature.
I have created a custome SharePoint security role (contribute role without the Delete right).
The goal of my SharePoint feature is the following:
When uploading a file to a SP Site, the name of the file needs to be renamed using the meta-data's selected. When uploading a file, a second form is asking the user to defined 3 or 4 meta-data's.
To rename the file, i have developed the following code:
Public override void ItemAdded(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
CallFunctionToUpdate();
});
}
Public override void ItemUpdated(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
CallFunctionToUpdate();
});
}
Public void CallFunctionToUpdate()
{
try
{
this.EventFiringEnabled = false;
using (SPWeb newWeb = newSite.OpenWeb(_properties.RelativeWebUrl))
{
SPListItem item = newWeb.Lists[_properties.ListId].GetItemById(_properties.ListItem.ID);
newFileName = FilenameManagementHelper.GenerateFilename(properties.ListItem);
currentName = properties.ListItem["Name"].ToString();
var extension = Path.GetExtension(currentName);
if (item["Title"] == null || item["Title"].ToString() != newFileName)
{
item["Title"] = newFileName;
item["Editor"] = new SPFieldUserValue(properties.OpenWeb(), properties.OpenWeb().CurrentUser.ID, properties.OpenWeb().CurrentUser.LoginName);
item.SystemUpdate();
}
if (currentName.Substring(0, currentName.Length - extension.Length) != newFileName)
{
SPList list = newWeb.Lists[_properties.List.Title];
string destUrl = list.RootFolder.Url + "/" + newFileName + extension;
SPFile fileToMove = list.Items[_properties.ListItemUniqueId].File;
SPFolder folder = newWeb.GetFolder(list.RootFolder.Url);
byte[] bin = fileToMove.OpenBinary();
folder.Files.Add(destUrl, bin, fileToMove.Properties, true);
fileToMove.Delete(); newWeb.Lists[list.RootFolder.Url].Update();
}
}
}
catch (Exception ex)
{
DocumentDiagnosticService.LogError(CategoryID.Error, string.Format("Error {0} for the file name - {1}", ex.Message, currentName));
}
finally
{
this.EventFiringEnabled = true;
}
}
Before renaming the file name, I'm updating the field (meta-data's) title and Editor. The second step will move the file (with the meta-data's and the history associated to the uploaded file)
I'm using the Elevated Mode because the user with a restricted Security role cannot delete. In the code developed I'm moving the file renamed and deleting the old file uploaded.
I found that approach because I need to keep the versioning. Updating directly the name of the file (like for the title) is not allowed and that's losing the history. Ex: A file will be uploaded, the name of the file will be updated using the Meta-data's. For the first version, there is no issue. Uploading a second file with the same meta-data's as there is already an existing file with the same name, that will generate an error. Using the Files.Add, that will oerride the current file and will keep the history.
My issue in this case: When the user is uploading the file, the fields Title and Editor are correctly replaced. Than is moving the file, renaming the field Name and deleting the old version. At this moment, the Modify by field is coming the SharePoint Sys Admin all the time.
How can i keep the Modifiy by with the name of the person who is uploading the file ?
EDIT:
Using the following code:
SPList list = newWeb.Lists[_properties.List.Title];
string destUrl = list.RootFolder.Url + "/" + newFileName + extension;
SPFile fileToMove = list.Items[_properties.ListItemUniqueId].File;
SPFolder folder = newWeb.GetFolder(list.RootFolder.Url);
byte[] bin = fileToMove.OpenBinary();
folder.Files.Add(destUrl, bin, fileToMove.Properties, true);
fileToMove.Delete();
Allow me to move the file with the meta-data's selected during the upload. I still have the versioning if a current version is already uploaded BUT the Modified By is SysAdmin.
Using the following code:
SPList list = newWeb.Lists[_properties.List.Title];
string destUrl = list.RootFolder.Url + "/" + newFileName + extension;
SPFile fileToMove = list.Items[_properties.ListItemUniqueId].File;
SPFolder folder = newWeb.GetFolder(list.RootFolder.Url);
byte[] bin = fileToMove.OpenBinary();
SPUser author = fileToMove.Author;
folder.Files.Add(destUrl, bin, author, author, DateTime.Now, DateTime.Now);
fileToMove.Delete();
Allow me to move the file and keep the history if i already have a version. I can now get the Modified By field filled by the real user who is uploading and not the SysAdmin BUT I'm losing the meta-data's selected during the upload.
Thank you for your support,
Fix.

Use item.Update() instead of SystemUpdate(). It should retain the identity of logged in user.

Thank you for your support.
I have solved my issue by using the following code:
folder.Files.Add(destUrl, bin, fileToMove.Properties, author, author, DateTime.Now, DateTime.Now, true);
Now, I have the Modified By value filled with the user who is uploading, the meta-data's are still there and the versioning too.

Related

Hyperlink to open/download a File (Acumatica)

Is there any way to make a hyperlink to a file that will open its contents or download it from the table it belongs? (In a sense, do exactly the same thing as AllowEdit but open/download the file instead.) Example:
Where the Default Specification files are from files found on the customer:
Please note that what displays is the comment of the file. If anyone has any suggestions on how to display the file name instead, that would be appreciated as well.
You can get the filename like this:
UploadFileMaintenance uploadFileMaintenance = PXGraph.CreateInstance<UploadFileMaintenance>();
foreach (Guid note in PXNoteAttribute.GetFileNotes(cache, dacRecord))
{
FileInfo file = uploadFileMaintenance.GetFileWithNoData(note);
PXTrace.WriteInformation(file.Name);
}
To download the file, create a DAC field of string type. You can initialize the string to the file name in the FieldDefaulting or FieldSelecting event. Declare an Action and use the LinkCommand attribute in the ASPX file to make that field control a link.
In that Action event handler, you can redirect the browser to the file in order to download/open it:
UploadFileMaintenance uploadFileMaintenance = PXGraph.CreateInstance<UploadFileMaintenance>();
Guid[] notes = PXNoteAttribute.GetFileNotes(cache, dacRecord);
if (notes != null && notes.Length > 0)
{
FileInfo downloadFile = uploadFileMaintenance.GetFile(notes[0]);
if (downloadFile != null)
{
throw new PXRedirectToFileException(downloadFile.UID, true);
}
}

How to load a txt file in MVC 5 respecting indentation and feed lines?

I am trying to load a text file in MCV5, I saw this piece of code works well
public ActionResult ReleaseNotes()
{ var fileContents = System.IO.File.ReadAllText(Server.MapPath(#"~/App_Data/ReleaseNotes.txt"));
return Content(fileContents); }
but I get something like:
Fixed an error in the user information tool introduced in 3.7.3--------------------------v 03.07.03--------------------------- Change 'Last Logon' to 'Last Connection' in the top right navigation web menu- Disable Shared Configuration admin page, when Shared Configuration feature is deactivated
instead of respecting the indentation and the feed lines of the original format
Fixed an error in the user information tool introduced in 3.7.3
--------------------------v 03.07.03---------------------------
Change 'Last Logon' to 'Last Connection' in the top right navigation web menu- Disable Shared Configuration admin page, when Shared Configuration feature is deactivated.
I have tried many solutions like:
public string ReleaseNotes()
{
string line,returnline="";
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader(#"~\App_Data\ReleaseNotes.txt");
while ((line = file.ReadLine()) != null)
returnline = returnline + line + "\t\n";
file.Close();
return returnline;}
Do you know if there is a special class that manages only text files and respects the original format ?
thanks and Regards,
You must modify the controller and the view using a ViewBag to export the datas like that
In the controller
string line;
System.IO.StreamReader file = new System.IO.StreamReader(#"your file txt");
var fileLines = new List<string>();
while ((line = file.ReadLine()) != null)
{
fileLines.Add(line);
ViewBag.File = fileLines;
return View();
In the View (cshtml file)
#{
string line;
foreach (var item in ViewBag.File)
{
<p>#item</p>
}}
It should work properly

how create document and library in liferay

Requirement: Adding Parent folders, Child folders and Their files to Document and Library from Particular location.
Case-1: If Folder is already exists then get that id and add file
( Here I am using
addFileEntry(repositoryId, folderId,sourceFileName, mimeType, title, description, changeLog, is, size, serviceContext) of DLAppServiceUtil class ).
Case-2: If Folder is not exits add folder then add file
(Here I am using for adding folder
addFolder() method of DLAppServiceUtil class)
My case its gives slow performance. That is the problem.
Which version of Liferay are you using?
The current trend is the following in 6.1+ (well, when it is correctly implemented, but you can build more or less on this with the new DLApp implementation):
Locate the parent folder id. Use the default from the DLFolderConstancts if you don't have any.
Assume the folder exists and try to get it.
It will throw you a NoSuch***Exception if not found. If this is the case, create the folder by hand
You could do something like this:
private Folder getOrCreateFolder(final ServiceContext serviceContext,
final long userId, final Group group, String folderName)
throws PortalException, SystemException {
final long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
final long repositoryId = group.getGroupId();
try {
final Folder prev = DLAppLocalServiceUtil.getFolder(
repositoryId, parentFolderId, folderName);
return prev;
} catch (final NoSuchFolderException e) {
final Folder newFolder = DLAppLocalServiceUtil.addFolder(userId,
repositoryId, parentFolderId, folderName,
"My cool new folder", serviceContext);
return newFolder;
}
}
The docs and stuff are absolutely leaky about why you call the addFolder() that way, take a look on the portal source. It's not that trivial but isn't that hard to get used to either.

Creating Sharepoint Directory Recurisvely

I am attempting to create a set of folders that comes in from a flat file in the manner of.
X/Y/Z
and I would like to create a directory for each of these but my memory of recursion has got me in knotts.
here is my code can someone advise.
public void CreateDirectory(SPFolderCollection oWeb, string folder)
{
SPFolder theFolder = oWeb.Add(folder);
theFolder.Update();
}
public void FolderCreator(SPWeb oWeb)
{
StreamReader reader = new StreamReader(this.txtFolders.Text);
while (reader.Peek() != -1)
{
string folderLine = reader.ReadLine();
if (folderLine.Contains("/"))
{
SPFolderCollection collection = oWeb.Folders["Documents"].SubFolders[folderLine.Split('/')[0]].SubFolders;
CreateDirectory(collection, folderLine);
}
SPFolderCollection newCollection = oWeb.Folders["Documents"].SubFolders;
CreateDirectory(newCollection, folderLine);
}
}
This does not work I am looking for it to do recrusion so if I pass
ABC/DEF/GHI
and
ABC/DEF
it will go and create the folders appropriately.
But I am stuck as how to do that.
The SPFileCollection.Add() methods allow you to pass in the full relative path of a file. So this may be an option assuming you aren't just generating a folder structure, which you may be doing, in which case this won't really work unless you create a temporary file and then delete it to keep the folder path.
web.Files.Add("/sites/somesite/shared documents/foldera/folderb/folderc/somefile.txt", stream);

Customizing upload file functionality in SharePoint picture library

Can anyone help me ,I want to customize upload functionality in which i want to validate the uploaded image type to the picture library
where can i set my script ?? Any one can advise ???
You might be Use ItemAdding. In ItemAdding Event Method just check extension of the Document before successfully uploaded to the Library.if unvalid document than through Error message
your code something like this :
protected string[] ValidExtensions = new string[] { "png", "jpeg", "gif"};
public override void ItemAdding(SPItemEventProperties properties)
{
string strFileExtension = Path.GetExtension(properties.AfterUrl);
bool isValidExtension = false;
string strValidFileTypes = string.Empty;
using (SPWeb web = properties.OpenWeb())
{
foreach (string strValidExt in ValidExtensions)
{
if (strFileExtension.ToLower().EndsWith(strValidExt.ToLower()))
{
isValidExtension = true;
}
strValidFileTypes += (string.IsNullOrEmpty(strValidFileTypes) ? "" : ", ") + strValidExt;
}
// Here i am going to check is this validate or not if not than redirect to the
//Error Message Page.
if (!isValidExtension)
{
properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
properties.RedirectUrl = properties.WebUrl + "/_layouts/error.aspx?ErrorText=" + "Only " + strValidFileTypes + " extenstions are allowed";
}
}
}
You could use SPItemEventReceiver for your library and add your logic into ItemUpdating() and ItemAdding() methods.
You can try creating a custom list template and replace the default NewForm.aspx and EditForm.aspx pages there. These custom form templates need not contain the same user controls and buttons as in the default picture library template. You could create a Silverlight web part with rich UI to upload images, e.g. The more you want to differ the more code you'll have to write...
An OOTB solution I can think of would be a workflow that you would force every new picture to run through but it would be quite an overkill for the end-user...
Of course, if you're able to validate by using just the meta-data in ItemAdding as the others suggest, it'd be a huge time-saver.
--- Ferda

Resources